From 6b43d1aa8abb278bcdc0acb84e260d0e52c48fec Mon Sep 17 00:00:00 2001 From: eitan schreiber Date: Tue, 19 Feb 2019 13:36:19 -0500 Subject: [PATCH] new data structure --- __tests__/Times.ts | 32 ++++++++++++++ src/Immutable.js | 3 ++ src/Times.js | 55 ++++++++++++++++++++++++ type-definitions/immutable.js.flow | 3 ++ type-definitions/tests/immutable-flow.js | 9 +++- 5 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 __tests__/Times.ts create mode 100644 src/Times.js diff --git a/__tests__/Times.ts b/__tests__/Times.ts new file mode 100644 index 000000000..9c503abff --- /dev/null +++ b/__tests__/Times.ts @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/// + +import { Times } from '../'; + +describe('Times', () => { + it('fixed times', () => { + const v = Times(5, n => n + 1); + expect(v.size).toBe(5); + expect(v.first()).toBe(2); + expect(v.rest().toArray()).toEqual([3, 4, 5, 6]); + expect(v.last()).toBe(6); + expect(v.butLast().toArray()).toEqual([2, 3, 4, 5]); + expect(v.toArray()).toEqual([2, 3, 4, 5, 6]); + }); + + it('defined seed', () => { + const v = Times(5, n => n + 1, 2); + expect(v.size).toBe(5); + expect(v.first()).toBe(3); + expect(v.rest().toArray()).toEqual([4, 5, 6, 7]); + expect(v.last()).toBe(7); + expect(v.butLast().toArray()).toEqual([3, 4, 5, 6]); + expect(v.toArray()).toEqual([3, 4, 5, 6, 7]); + }); +}); diff --git a/src/Immutable.js b/src/Immutable.js index de672c8a7..d26da1c59 100644 --- a/src/Immutable.js +++ b/src/Immutable.js @@ -15,6 +15,7 @@ import { Set } from './Set'; import { Record } from './Record'; import { Range } from './Range'; import { Repeat } from './Repeat'; +import { Times } from './Times'; import { is } from './is'; import { fromJS } from './fromJS'; @@ -71,6 +72,7 @@ export default { Record: Record, Range: Range, Repeat: Repeat, + Times: Times, is: is, fromJS: fromJS, @@ -125,6 +127,7 @@ export { Record, Range, Repeat, + Times, is, fromJS, hash, diff --git a/src/Times.js b/src/Times.js new file mode 100644 index 000000000..07204450b --- /dev/null +++ b/src/Times.js @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { ArraySeq } from './Seq'; + +import deepEqual from './utils/deepEqual'; + +/** + * Calls func with seed as the argument and returns an Seq.Indexed of the results, + * times and func are required and seed defaults to 1 + */ +export class Times extends ArraySeq { + constructor(times, func, seed) { + if (!(this instanceof Times)) { + return new Times(times, func, seed); + } + const source = []; + seed = seed || 1; + times = Math.max(0, times); + this._times = times; + this._seed = seed; + this._func = func; + while (times > 0) { + seed = func(seed); + source.push(seed); + times--; + } + super(source); + if (this.size === 0) { + if (EMPTY_TIMES) { + return EMPTY_TIMES; + } + EMPTY_TIMES = this; + } + } + toString() { + if (this.size === 0) { + return 'Times []'; + } + return this.toArray().toString(); + } + equals(other) { + return other instanceof Times + ? this._times === other._times && + this._seed === other._seed && + this._func === other._func + : deepEqual(this, other); + } +} + +let EMPTY_TIMES; diff --git a/type-definitions/immutable.js.flow b/type-definitions/immutable.js.flow index 2b37f4143..e4719a5a2 100644 --- a/type-definitions/immutable.js.flow +++ b/type-definitions/immutable.js.flow @@ -1380,6 +1380,7 @@ declare class Stack<+T> extends IndexedCollection { declare function Range(start?: number, end?: number, step?: number): IndexedSeq; declare function Repeat(value: T, times?: number): IndexedSeq; +declare function Times(times: number, callback: (value: any) => any, seed?: any): IndexedSeq; // The type of a Record factory function. type RecordFactory = Class>; @@ -1581,6 +1582,7 @@ export { OrderedSet, Range, Repeat, + Times, Record, Set, Stack, @@ -1624,6 +1626,7 @@ export default { OrderedSet, Range, Repeat, + Times, Record, Set, Stack, diff --git a/type-definitions/tests/immutable-flow.js b/type-definitions/tests/immutable-flow.js index 0bc7289b0..2b9e2bbba 100644 --- a/type-definitions/tests/immutable-flow.js +++ b/type-definitions/tests/immutable-flow.js @@ -18,6 +18,7 @@ import Immutable, { Seq, Range, Repeat, + Times, Record, OrderedMap, OrderedSet, @@ -64,6 +65,7 @@ const ImmutableSet = Immutable.Set const ImmutableKeyedCollection: KeyedCollection<*, *> = Immutable.Collection.Keyed() const ImmutableRange = Immutable.Range const ImmutableRepeat = Immutable.Repeat +const ImmutableTimes = Immutable.Times const ImmutableIndexedSeq: IndexedSeq<*> = Immutable.Seq.Indexed() const Immutable2List = Immutable2.List @@ -73,6 +75,7 @@ const Immutable2Set = Immutable2.Set const Immutable2KeyedCollection: Immutable2.KeyedCollection<*, *> = Immutable2.Collection.Keyed() const Immutable2Range = Immutable2.Range const Immutable2Repeat = Immutable2.Repeat +const Immutable2Times = Immutable2.Times const Immutable2IndexedSeq: Immutable2.IndexedSeq<*> = Immutable2.Seq.Indexed() var defaultExport: List<*> = Immutable.List(); @@ -884,18 +887,20 @@ numberStack = Stack([1]).flatMap((value, index, iter) => ['a']) numberStack = Stack([1]).flatten() numberStack = Stack(['a']).flatten() -/* Range & Repeat */ +/* Range & Repeat & Times */ // `{}` provide namespaces { const numberSequence: IndexedSeq = Range(0, 0, 0) } { const numberSequence: IndexedSeq = Repeat(1, 5) } +{ const numberSequence: IndexedSeq = Times(5, n => n + 1) } { const stringSequence: IndexedSeq = Repeat('a', 5) } // $ExpectError { const stringSequence: IndexedSeq = Repeat(0, 1) } // $ExpectError { const stringSequence: IndexedSeq = Range(0, 0, 0) } - +// $ExpectError +{ const stringSequence: IndexedSeq = Times('a', n => n + 1) } /* Seq */ let numberSeq = Seq([ 1, 2, 3 ])