Skip to content

Commit

Permalink
Add flatmap (#6)
Browse files Browse the repository at this point in the history
Add flatmap
  • Loading branch information
planttheidea authored Jun 15, 2019
2 parents f38b847 + b5a45a1 commit 20beb0d
Show file tree
Hide file tree
Showing 44 changed files with 392 additions and 13 deletions.
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ import { map, reduce, someObject } from 'inline-loops.macro';

function contrivedExample(array) {
const doubled = map(array, (value) => value * 2);
const doubleObject = reduce(doubled, (object, value) => ({
...object,
[value]: value
const doubleObject = reduce(doubled, (object, value) => ({
...object,
[value]: value
}, {});

if (someObject(doubleObject, (value) => value > 100)) {
Expand All @@ -55,6 +55,9 @@ function contrivedExample(array) {
- `findIndex` ([MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex))
- `findIndexRight` => same as `findIndex`, but iterating in reverse
- `findKey` => same as `findIndex` but iterating over objects intead of arrays
- `flatMap` ([MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap))
- `flatMapRight` => same as `findIndex`, but iterating in reverse
- There is no object method, as the use cases and expected results are not clearly defined, nor is the expected outcome obvious
- `forEach` ([MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach))
- `forEachRight` => same as `forEach`, but iterating in reverse
- `forEachObject` => same as `forEach` but iterating over objects intead of arrays
Expand Down Expand Up @@ -110,9 +113,7 @@ Notice that there is no reference to the original function, because it used the
```javascript
// this
const isAllTuples = every(array, tuple =>
every(tuple, (value) => Array.isArray(value) && value.length === 2)
);
const isAllTuples = every(array, tuple => every(tuple, value => Array.isArray(value) && value.length === 2));

// becomes this
let _result = true;
Expand All @@ -130,7 +131,7 @@ for (let _key = 0, _length = array.length, _value; _key < _length; ++_key) {
break;
}
}

if (!_result2) {
_result = false;
break;
Expand Down Expand Up @@ -172,7 +173,7 @@ If you need to incorporate this, you can do it one of two ways:
**Add filtering (iterates twice, but arguably cleaner semantics)**
```javascript
const raw = mapObject(object, (value, key) => object.hasOwnProperty(key) ? value * 2 : null);
const raw = mapObject(object, (value, key) => (object.hasOwnProperty(key) ? value * 2 : null));
const doubled = filterObject(raw, value => value !== null);
```
Expand Down
3 changes: 3 additions & 0 deletions __tests__/__fixtures__/cached/flatMap/code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { flatMap } from '../../../../src/inline-loops.macro';

const flattened = flatMap(array, fn);
9 changes: 9 additions & 0 deletions __tests__/__fixtures__/cached/flatMap/output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
let _result = [];

for (let _key = 0, _length = array.length, _value; _key < _length; ++_key) {
_value = array[_key];

_result.push.apply(_result, fn(_value, _key, array));
}

const flattened = _result;
3 changes: 3 additions & 0 deletions __tests__/__fixtures__/cached/flatMapRight/code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { flatMapRight } from '../../../../src/inline-loops.macro';

const flattened = flatMapRight(array, fn);
9 changes: 9 additions & 0 deletions __tests__/__fixtures__/cached/flatMapRight/output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
let _result = [];

for (let _key = array.length - 1, _value; _key >= 0; --_key) {
_value = array[_key];

_result.push.apply(_result, fn(_value, _key, array));
}

const flattened = _result;
5 changes: 5 additions & 0 deletions __tests__/__fixtures__/complex/destructured-params/code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { forEach } from '../../../../src/inline-loops.macro';

forEach([], ([a, b]) => {
console.log(a, b);
});
11 changes: 11 additions & 0 deletions __tests__/__fixtures__/complex/destructured-params/output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const _iterable = [];

const _fn = ([a, b]) => {
console.log(a, b);
};

for (let _key = 0, _length = _iterable.length, _value; _key < _length; ++_key) {
_value = _iterable[_key];

_fn(_value, _key, _iterable);
}
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { flatMap } from '../../../../src/inline-loops.macro';

const flattened = flatMap(array, entry => [entry[0]]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
let _result = [];

for (let _key = 0, _length = array.length, _value; _key < _length; ++_key) {
_value = array[_key];

_result.push.apply(_result, [_value[0]]);
}

const flattened = _result;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { flatMapRight } from '../../../../src/inline-loops.macro';

const flattened = flatMapRight(array, entry => [entry[0]]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
let _result = [];

for (let _key = array.length - 1, _value; _key >= 0; --_key) {
_value = array[_key];

_result.push.apply(_result, [_value[0]]);
}

const flattened = _result;
5 changes: 5 additions & 0 deletions __tests__/__fixtures__/inlined-arrow-return/flatMap/code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { flatMap } from '../../../../src/inline-loops.macro';

const flattened = flatMap(array, entry => {
return [entry[0]];
});
9 changes: 9 additions & 0 deletions __tests__/__fixtures__/inlined-arrow-return/flatMap/output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
let _result = [];

for (let _key = 0, _length = array.length, _value; _key < _length; ++_key) {
_value = array[_key];

_result.push.apply(_result, [_value[0]]);
}

const flattened = _result;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { flatMapRight } from '../../../../src/inline-loops.macro';

const flattened = flatMapRight(array, entry => {
return [entry[0]];
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
let _result = [];

for (let _key = array.length - 1, _value; _key >= 0; --_key) {
_value = array[_key];

_result.push.apply(_result, [_value[0]]);
}

const flattened = _result;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { flatMap } from '../../../../src/inline-loops.macro';

const flattened = flatMap(array, function(entry) {
return [entry[0]];
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
let _result = [];

for (let _key = 0, _length = array.length, _value; _key < _length; ++_key) {
_value = array[_key];

_result.push.apply(_result, [_value[0]]);
}

const flattened = _result;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { flatMapRight } from '../../../../src/inline-loops.macro';

const flattened = flatMapRight(array, function(entry) {
return [entry[0]];
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
let _result = [];

for (let _key = array.length - 1, _value; _key >= 0; --_key) {
_value = array[_key];

_result.push.apply(_result, [_value[0]]);
}

const flattened = _result;
7 changes: 7 additions & 0 deletions __tests__/__fixtures__/uncached/flatMap/code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { flatMap } from '../../../../src/inline-loops.macro';

const flattened = flatMap([['foo', 'bar'], ['bar', 'baz']], (entry) => {
const [first] = entry;

return [first];
});
16 changes: 16 additions & 0 deletions __tests__/__fixtures__/uncached/flatMap/output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const _iterable = [['foo', 'bar'], ['bar', 'baz']];

const _fn = entry => {
const [first] = entry;
return [first];
};

let _result = [];

for (let _key = 0, _length = _iterable.length, _value; _key < _length; ++_key) {
_value = _iterable[_key];

_result.push.apply(_result, _fn(_value, _key, _iterable));
}

const flattened = _result;
7 changes: 7 additions & 0 deletions __tests__/__fixtures__/uncached/flatMapRight/code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { flatMapRight } from '../../../../src/inline-loops.macro';

const flattened = flatMapRight([['foo', 'bar'], ['bar', 'baz']], (entry) => {
const [first] = entry;

return [first];
});
16 changes: 16 additions & 0 deletions __tests__/__fixtures__/uncached/flatMapRight/output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const _iterable = [['foo', 'bar'], ['bar', 'baz']];

const _fn = entry => {
const [first] = entry;
return [first];
};

let _result = [];

for (let _key = _iterable.length - 1, _value; _key >= 0; --_key) {
_value = _iterable[_key];

_result.push.apply(_result, _fn(_value, _key, _iterable));
}

const flattened = _result;
154 changes: 154 additions & 0 deletions __tests__/__runtime__/flatMap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/* eslint-disable */

const { flatMap, flatMapRight } = require('../../src/inline-loops.macro');

const { deepEqual: isEqual } = require('fast-equals');

const ARRAY = [[1], [2], [3], [4], [5], [6]];

const withTriples = value => [value, value * 2, value * 3];

const BAD_ARRAY_RESULT = [...ARRAY];
const ARRAY_RESULT = ARRAY.reduce((accumulator, value) => {
const result = withTriples(value);

accumulator.push(...result);

return accumulator;
}, []);

const BAD_DECREMENTING_ARRAY_RESULT = [...ARRAY].reverse();
const DECREMENTING_ARRAY_RESULT = ARRAY.reduceRight((accumulator, value) => {
const result = withTriples(value);

accumulator.push(...result);

return accumulator;
}, []);

module.exports = {
cached: {
decrementing: {
false: isEqual(flatMapRight(ARRAY, withTriples), BAD_DECREMENTING_ARRAY_RESULT),
true: isEqual(flatMapRight(ARRAY, withTriples), DECREMENTING_ARRAY_RESULT),
},
standard: {
false: isEqual(flatMap(ARRAY, withTriples), BAD_ARRAY_RESULT),
true: isEqual(flatMap(ARRAY, withTriples), ARRAY_RESULT),
},
},
inlinedArrowExpression: {
decrementing: {
false: isEqual(
flatMapRight(ARRAY, value => [value, value * 2, value * 3]),
BAD_DECREMENTING_ARRAY_RESULT,
),
true: isEqual(
flatMapRight(ARRAY, value => [value, value * 2, value * 3]),
DECREMENTING_ARRAY_RESULT,
),
},
standard: {
false: isEqual(flatMap(ARRAY, value => [value, value * 2, value * 3]), BAD_ARRAY_RESULT),
true: isEqual(flatMap(ARRAY, value => [value, value * 2, value * 3]), ARRAY_RESULT),
},
},
inlinedArrowReturn: {
decrementing: {
false: isEqual(
flatMapRight(ARRAY, value => {
return [value, value * 2, value * 3];
}),
BAD_DECREMENTING_ARRAY_RESULT,
),
true: isEqual(
flatMapRight(ARRAY, value => {
return [value, value * 2, value * 3];
}),
DECREMENTING_ARRAY_RESULT,
),
},
standard: {
false: isEqual(
flatMap(ARRAY, value => {
return [value, value * 2, value * 3];
}),
BAD_ARRAY_RESULT,
),
true: isEqual(
flatMap(ARRAY, value => {
return [value, value * 2, value * 3];
}),
ARRAY_RESULT,
),
},
},
inlinedFunctionReturn: {
decrementing: {
false: isEqual(
flatMapRight(ARRAY, function(value) {
return [value, value * 2, value * 3];
}),
BAD_DECREMENTING_ARRAY_RESULT,
),
true: isEqual(
flatMapRight(ARRAY, function(value) {
return [value, value * 2, value * 3];
}),
DECREMENTING_ARRAY_RESULT,
),
},
standard: {
false: isEqual(
flatMap(ARRAY, function(value) {
return [value, value * 2, value * 3];
}),
BAD_ARRAY_RESULT,
),
true: isEqual(
flatMap(ARRAY, function(value) {
return [value, value * 2, value * 3];
}),
ARRAY_RESULT,
),
},
},
uncached: {
decrementing: {
false: isEqual(
flatMapRight([].concat(ARRAY), value => {
const withTriples = [value, value * 2, value * 3];

return withTriples;
}),
BAD_DECREMENTING_ARRAY_RESULT,
),
true: isEqual(
flatMapRight([].concat(ARRAY), value => {
const withTriples = [value, value * 2, value * 3];

return withTriples;
}),
DECREMENTING_ARRAY_RESULT,
),
},
standard: {
false: isEqual(
flatMap([].concat(ARRAY), value => {
const withTriples = [value, value * 2, value * 3];

return withTriples;
}),
BAD_ARRAY_RESULT,
),
true: isEqual(
flatMap([].concat(ARRAY), value => {
const withTriples = [value, value * 2, value * 3];

return withTriples;
}),
ARRAY_RESULT,
),
},
},
};
Loading

0 comments on commit 20beb0d

Please sign in to comment.