Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions internal/iterableSerialReduce.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* eslint-disable */
const iterableSerialReduce = (func, initial, iterable, promise = Promise.resolve(initial)) => {
const iterator = iterable[Symbol.iterator]()
const { value, done } = iterator.next()
return done
? promise
: promise.then(() =>
iterableSerialReduce(
func,
initial,
iterator,
promise.then(acc => func(acc, value))
))
}

module.exports = iterableSerialReduce
13 changes: 0 additions & 13 deletions internal/serialReduce.js

This file was deleted.

22 changes: 20 additions & 2 deletions list/__tests__/filter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,35 @@ const filter = require("../filter")
describe("list/filter", () => {
const isOdd = num => num % 2 !== 0
const asyncIsOdd = num => Promise.resolve(num).then(isOdd)
function* iterator() {
yield 1
yield 2
yield 3
}

test("sync filters", () => {
test("sync array", () => {
const expected = [1, 3]
const actual = filter(isOdd)([1, 2, 3])
expect(actual).toMatchObject(expected)
})

test("async filters", () => {
test("async array", () => {
expect.assertions(1)
const expected = [1, 3]
const actual = filter(asyncIsOdd)([1, 2, 3])
return expect(actual).resolves.toMatchObject(expected)
})

test("sync iterator", () => {
const expected = [1, 3]
const actual = filter(isOdd)(iterator())
expect(actual).toMatchObject(expected)
})

test("async iterator", () => {
expect.assertions(1)
const expected = [1, 3]
const actual = filter(asyncIsOdd)(iterator())
return expect(actual).resolves.toMatchObject(expected)
})
})
23 changes: 21 additions & 2 deletions list/__tests__/map.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,37 @@ const map = require("../map")
describe("list/map", () => {
const double = num => num * 2
const asyncDouble = num => Promise.resolve(num).then(double)
function* iterator() {
yield 1
yield 2
yield 3
}

test("sync map", () => {
test("sync array", () => {
expect.assertions(1)
const expected = [2, 4, 6]
const actual = map(double)([1, 2, 3])
expect(actual).toMatchObject(expected)
})

test("async maps", () => {
test("async array", () => {
expect.assertions(1)
const expected = [2, 4, 6]
const actual = map(asyncDouble)([1, 2, 3])
return expect(actual).resolves.toMatchObject(expected)
})

test("sync iterable", () => {
expect.assertions(1)
const expected = [2, 4, 6]
const actual = map(double)(iterator())
expect(actual).toMatchObject(expected)
})

test("async iterable", () => {
expect.assertions(1)
const expected = [2, 4, 6]
const actual = map(asyncDouble)(iterator())
return expect(actual).resolves.toMatchObject(expected)
})
})
22 changes: 20 additions & 2 deletions list/__tests__/reduce.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,35 @@ const reduce = require("../reduce")
describe("list/reduce", () => {
const add = x => y => x + y
const asyncAdd = x => y => Promise.resolve(x).then(add(y))
function* iterator() {
yield 1
yield 2
yield 3
}

test("sync reduces", () => {
test("sync array", () => {
const expected = 6
const actual = reduce(add)(0)([1, 2, 3])
expect(actual).toBe(expected)
})

test("async reduces", () => {
test("async array", () => {
expect.assertions(1)
const expected = 6
const actual = reduce(asyncAdd)(0)([1, 2, 3])
return expect(actual).resolves.toBe(expected)
})

test("sync iterable", () => {
const expected = 6
const actual = reduce(add)(0)(iterator())
expect(actual).toBe(expected)
})

test("async iterable", () => {
expect.assertions(1)
const expected = 6
const actual = reduce(asyncAdd)(0)(iterator())
return expect(actual).resolves.toBe(expected)
})
})
19 changes: 12 additions & 7 deletions list/filter.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable */
const isThenable = require('../internal/isThenable')
const serialReduce = require('../internal/serialReduce')
const iterableSerialReduce = require('../internal/iterableSerialReduce')

const asyncFilterReducer = func => (acc, x) => {
const result = func(x)
Expand All @@ -11,15 +11,20 @@ const asyncFilterReducer = func => (acc, x) => {

const filter = func => iterable => {
const values = []
for (let i = 0; i < iterable.length; i++) {
const x = iterable[i]
const result = func(x)
const iterator = iterable[Symbol.iterator]()
var { value, done } = iterator.next()

while (!done) {
const result = func(value)
if (isThenable(result)) {
return serialReduce(asyncFilterReducer(func), [], values.concat(iterable), i + 1, result.then(() => [ x ]))
} else if (result) {
values.push(x)
return iterableSerialReduce(asyncFilterReducer(func), null, iterator, result.then(() => [ value ]))
}
if (result) {
values.push(value)
}
var { value, done } = iterator.next()
}

return values
}

Expand Down
20 changes: 13 additions & 7 deletions list/map.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable */
const isThenable = require('../internal/isThenable')
const serialReduce = require('../internal/serialReduce')
const iterableSerialReduce = require('../internal/iterableSerialReduce')

const asyncMapReducer = func => (acc, x) => {
const result = func(x)
Expand All @@ -9,16 +9,22 @@ const asyncMapReducer = func => (acc, x) => {
: (acc.push(result), acc)
}

const map = func => xs => {
const map = func => iterable => {
const values = []
for (let i = 0; i < xs.length; i++) {
const result = func(xs[i])
const iterator = iterable[Symbol.iterator]()
var { value, done } = iterator.next()

while (!done) {
const result = func(value)

if (isThenable(result)) {
return serialReduce(asyncMapReducer(func), [], values.concat(xs), i + 1, result.then(v => [ v ]))
} else {
values.push(result)
return iterableSerialReduce(asyncMapReducer(func), null, iterator, result.then(v => [ v ]))
}

values.push(result)
var { value, done } = iterator.next()
}

return values
}

Expand Down
16 changes: 10 additions & 6 deletions list/reduce.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
/* eslint-disable */
const isThenable = require('../internal/isThenable')
const serialReduce = require('../internal/serialReduce')
const iterableSerialReduce = require('../internal/iterableSerialReduce')

const reduce = func => initial => list => {
const reduce = func => initial => iterable => {
let acc = initial
for (let i = 0; i < list.length; i++) {
acc = func(acc)(list[i])
const iterator = iterable[Symbol.iterator]()
var { value, done } = iterator.next()

while (!done) {
acc = func(acc)(value)
if (isThenable(acc)) {
return serialReduce((a, b) => func(a)(b), acc, list, i + 1, acc)
return iterableSerialReduce((a, b) => func(a)(b), null, iterator, acc)
}
var { value, done } = iterator.next()
}
// Array.prototype.reduce.call (list, (acc, val) => func (acc) (val), initial)

return acc
}

Expand Down