Skip to content

Commit

Permalink
feat(iterator): insert move orderby
Browse files Browse the repository at this point in the history
  • Loading branch information
Hfutsora committed Oct 8, 2024
1 parent 400c28f commit f49cbed
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 3 deletions.
63 changes: 61 additions & 2 deletions src/Iterator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { getOrElse, Maybe, none, some, toUndefined } from './Maybe'
import { flow, pipe } from './Pipe'
import { Predicate } from './Predicate'
import { abs } from './Math'
import * as E from './Effect';


export const IterKind = Symbol('Iterator')
Expand Down Expand Up @@ -59,11 +60,47 @@ export function* push<A>(a: Iterable<A>, ...as: A[]): Iterable<A> {
yield* as
}

/**
* Returns an iterator with the elements inserted.
*
* @example
*
* ```ts
* assert.deepStrictEqual(pipe(of(1, 2, 3), insert(1, 4), collect), [1, 4, 2, 3])
* ```
*/
export const insert = <A>(index: number, ...as: A[]): (a: Iterable<A>) => Iterable<A> => a => {
const collects = collect(a)
collects.splice(index, 0, ...as)

return collects
}

/**
* Returns an iterator with an element moved to the target position.
*
* @example
*
* ```ts
* assert.deepStrictEqual(pipe(of(1, 2, 3), move(1, 2), collect), [1, 3, 2])
* ```
*/
export const move = <A>(from: number, to: number): (a: Iterable<A>) => Iterable<A> => a => {
const as = collect(a)

if (!(from < 0 || from >= as.length || to < 0 || to >= as.length)) {
const [moved] = as.splice(from, 1)
as.splice(to, 0, moved)
}

return as
}

/**
* Returns an iterator with the elements at start.
*/
export function* unshift<T>(a: Iterable<T>, ...items: T[]): Iterable<T> {
yield* items
export function* unshift<T>(a: Iterable<T>, ...as: T[]): Iterable<T> {
yield* as
yield* a
}

Expand Down Expand Up @@ -564,6 +601,28 @@ export const chainRec = <A, B>(f: (a: A) => Iterable<Either<A, B>>) => function*
return yield* out
}

/**
* Returns a sorted iterator of objects based on the specified order.
*
* @example
*
* ```ts
* assert.deepStrictEqual(orderBy([{ id: 1 }, { id: 2 }, { id: 3 }], 'id', [3, 2, 1]), [{ id: 3 }, { id: 2 }, { id: 1 }])
* ```
*/
export const orderBy = <
A extends Record<string, any>,
K extends keyof A,
>(
key: K,
to: A[K][]
) => (as: Iterable<A>): Iterable<A> =>
pipe(
as,
collect,
E.ap(as => as.sort((a, b) => to.indexOf(a[key]) - to.indexOf(b[key])))
)

/**
* Creates an `Iter` from an iterator.
*
Expand Down
14 changes: 13 additions & 1 deletion test/Iterator.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { left, right } from '../src/Either'
import { alt, ap, chain, chainRec, collect, concat, filter, isEmpty, iter, Iter, join, map, of, reduce, replicate, to, zero, tryTail, tryHead, group, nth } from '../src/Iterator'
import { alt, ap, chain, chainRec, collect, concat, filter, isEmpty, iter, Iter, join, map, of, reduce, replicate, to, zero, tryTail, tryHead, group, nth, orderBy, move, insert } from '../src/Iterator';
import { none, some } from '../src/Maybe'
import { flow, pipe } from '../src/Pipe'

Expand All @@ -20,6 +20,14 @@ it('push', () => {
expect(iter([1]).push(2, 3).collect()).toEqual([1, 2, 3])
})

it('insert', () => {
expect(pipe(of(1, 2, 3), insert(1, 4), collect)).toEqual([1, 4, 2, 3])
})

it('move', () => {
expect(pipe(of(1, 2, 3), move(1, 2), collect)).toEqual([1, 3, 2])
})

it('toArray', () => {
expect(iter([1, 2, 3]).toArray()).toEqual([1, 2, 3])
expect(iter(new Set([1, 2, 3])).toArray()).toEqual([1, 2, 3])
Expand Down Expand Up @@ -241,6 +249,10 @@ it('concat', () => {
expect(Iter.of(1).concat(['2', 3], [4, 5]))
})

it('orderBy', () => {
expect(pipe(of({ id: 1 }, { id: 2 }, { id: 3 }), orderBy('id', [3, 2, 1]), collect)).toEqual([{ id: 3 }, { id: 2 }, { id: 1 }])
})

it('compose1', () => {
const size = 2

Expand Down

0 comments on commit f49cbed

Please sign in to comment.