diff --git a/Maths/FindMinIterator.js b/Maths/FindMinIterator.js new file mode 100644 index 000000000..fc1c7d007 --- /dev/null +++ b/Maths/FindMinIterator.js @@ -0,0 +1,36 @@ +/** + * @function FindMinIterator + * @description Function to find the minimum number given in an array. + */ + +const FindMinIterator = (_iterable, _selector = undefined) => { + let min + + const iterator = _iterable[Symbol.iterator]() + if (!_selector) { + let current = iterator.next() + if (current.done) { return undefined } + min = current.value + + current = iterator.next() + while (!current.done) { + const x = current.value + if (x < min) { min = x } + current = iterator.next() + } + } else { + let current = iterator.next() + if (current.done) { return undefined } + min = _selector(current.value) + + current = iterator.next() + while (!current.done) { + const x = _selector(current.value) + if (x < min) { min = x } + current = iterator.next() + } + } + return min +} + +export { FindMinIterator } diff --git a/Maths/test/FindMinIterator.test.js b/Maths/test/FindMinIterator.test.js new file mode 100644 index 000000000..9f4200dc1 --- /dev/null +++ b/Maths/test/FindMinIterator.test.js @@ -0,0 +1,54 @@ +import { FindMinIterator } from '../FindMinIterator' + +describe('FindMinIterator', () => { + test('given empty array then min is undefined', () => { + expect(FindMinIterator([])).toBeUndefined() + }) + + test('given single value array then min is found', () => { + expect(FindMinIterator([1])).toBe(1) + expect(FindMinIterator([-1])).toBe(-1) + expect(FindMinIterator([0])).toBe(0) + }) + + test('given array then min is found', () => { + expect(FindMinIterator([1, 2])).toBe(1) + expect(FindMinIterator([-1, 10])).toBe(-1) + expect(FindMinIterator([0, 100])).toBe(0) + expect(FindMinIterator([100, 0])).toBe(0) + expect(FindMinIterator([100, 50, 20, 0, -100, 0, 2, 30, 45, 99, 104, 23])).toBe(-100) + }) + + test('given empty generator then min is undefined', () => { + const src = function* () { } // eslint-disable-line + expect(FindMinIterator(src())).toBeUndefined() + }) + + test('given generator then min is found', () => { + const src = function* () { // eslint-disable-line + yield 1 + yield -1 + yield 0 + } + expect(FindMinIterator(src())).toBe(-1) + }) + + test('given string generator then min string length is found', () => { + const src = function* () { // eslint-disable-line + yield 'abc' + yield 'de' + yield 'qwerty' + } + expect(FindMinIterator(src(), _x => _x.length)).toBe(2) + }) + + test('given array of objects then min accessor is found', () => { + const array = [ + { name: 'Item #1', price: 1.0 }, + { name: 'Item #2', price: 0.0 }, + { name: 'Item #3', price: -1.0 } + ] + expect(FindMinIterator(array, _x => _x.price)).toBe(-1) + expect(FindMinIterator(array, _x => _x.name)).toBe('Item #1') + }) +})