Skip to content

Commit

Permalink
Merge pull request #23 from Jozty/dev-ss
Browse files Browse the repository at this point in the history
add functions
  • Loading branch information
singla-shivam authored Jun 4, 2020
2 parents a6e232d + c24b660 commit d879264
Show file tree
Hide file tree
Showing 22 changed files with 703 additions and 0 deletions.
21 changes: 21 additions & 0 deletions any.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Predicate1, Curry2 } from "./utils/types.ts"
import { dispatch } from './utils/dispatch.ts'
import AnyTransformer from "./utils/Transformers/any.ts"
import curryN from './utils/curry_n.ts'

function _any<T>(predicate: Predicate1<T>, list: T[]) {
for(let i = 0; i < list.length; i++) {
if(predicate(list[i])) return true
}
return false
}

const dispatched = dispatch(AnyTransformer, _any)

/**
* Return `true` if any the elements of the functor match `predicate`
* `false` otherwise
*
* Acts as a transducer if a transformer is passed in place of `functor`
*/
export const any: Curry2<Predicate1, any[]> = curryN(2, dispatched)
25 changes: 25 additions & 0 deletions aperture.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { dispatch } from "./utils/dispatch.ts"
import ApertureTransformer from "./utils/Transformers/aperture.ts"
import curryN from "./utils/curry_n.ts"
import { Curry2 } from "./utils/types.ts"

function _aperture<T>(n: number, list: T[]) {
const len = list.length - n + 1
const result = new Array(Math.max(0, len))

for (let i = 0; i < len; i++) {
result[i] = list.slice(i, i + n)
}

return result
}

const dispatched = dispatch(ApertureTransformer as any, _aperture)

/**
* Returns a new list, composed of n-tuples of consecutive elements. If `n` is
* greater than the length of the list, an empty list is returned.
*
* Acts as a transducer if a transformer is passed in place of `list`
*/
export const aperture: Curry2<number, any[]> = curryN(2, dispatched)
20 changes: 20 additions & 0 deletions endsWith.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { equals } from "./equals.ts"
import { takeLast } from "./takeLast.ts"
import curryN from "./utils/curry_n.ts"
import { Curry2 } from "./utils/types.ts"

function _endsWith<T>(suffix: T[] | string, functor: T[] | string) {
const suffixF = takeLast(suffix.length, functor)
return equals(suffix, suffixF)
}

/**
* checks if `functor` ends with `suffix`
*
* Fae.endsWith('c', 'abc') //=> true
* Fae.endsWith('b', 'abc') //=> false
* Fae.endsWith(['c'], ['a', 'b', 'c']) //=> true
* Fae.endsWith(['b'], ['a', 'b', 'c']) //=> false
*
*/
export const endsWith: Curry2<any[] | string, any[] | string, boolean> = curryN(2, _endsWith)
24 changes: 24 additions & 0 deletions find.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Predicate1, Curry2 } from "./utils/types.ts"
import curryN from "./utils/curry_n.ts"
import { dispatch } from "./utils/dispatch.ts"
import FindTransformer from "./utils/Transformers/find.ts"

function _find<T>(predicate: Predicate1<T>, list: T[]) {
for(let i = 0; i < list.length; i++) {
if(predicate(list[i])) return list[i]
}
}

const dispatched = dispatch(FindTransformer, _find)

/**
* Returns the first element of the list which matches the predicate, or
* `undefined` if no element matches.
*
* Acts as a transducer if a transformer is passed in place of `list`
*
* const xs = [{a: 1}, {a: 2}, {a: 3}]
* Fae.find(Fae.propEq('a', 2))(xs) //=> {a: 2}
* Fae.find(Fae.propEq('a', 4))(xs) //=> undefined
*/
export const find: Curry2<Predicate1, any[], any> = curryN(2, dispatched)
24 changes: 24 additions & 0 deletions findLast.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Predicate1, Curry2 } from "./utils/types.ts"
import curryN from "./utils/curry_n.ts"
import { dispatch } from "./utils/dispatch.ts"
import FindLastTransformer from "./utils/Transformers/findLast.ts"

function _findLast<T>(predicate: Predicate1<T>, list: T[]) {
for(let i = list.length - 1; i >= 0; i--) {
if(predicate(list[i])) return list[i]
}
}

const dispatched = dispatch(FindLastTransformer, _findLast)

/**
* Returns the last element of the list which matches the predicate, or
* `undefined` if no element matches.
*
* Acts as a transducer if a transformer is passed in place of `list`
*
* const xs = [{a: 1, b: 0}, {a:1, b: 1}]
* Fae.findLast(Fae.propEq('a', 1))(xs) //=> {a: 1, b: 1}
* Fae.findLast(Fae.propEq('a', 4))(xs) //=> undefined
*/
export const findLast: Curry2<Predicate1, any[], any> = curryN(2, dispatched)
25 changes: 25 additions & 0 deletions findLastIndex.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Predicate1, Curry2 } from "./utils/types.ts"
import curryN from "./utils/curry_n.ts"
import { dispatch } from "./utils/dispatch.ts"
import FindLastIdxTransformer from "./utils/Transformers/findLastIndex.ts"

function _findLastIndex<T>(predicate: Predicate1, list: T[] | string ) {
for(let i = list.length - 1; i >= 0; i--) {
if(predicate(list[i])) return i
}
return -1
}

const dispatched = dispatch(FindLastIdxTransformer, _findLastIndex)

/**
* Returns index of last element of the list which matches the predicate, or
* `-1` if no element matches.
*
* Acts as a transducer if a transformer is passed in place of `list`
*
* const xs = [{a: 1}, {a: 2}, {a: 3}]
* Fae.find(Fae.propEq('a', 2))(xs) //=> {a: 2}
* Fae.find(Fae.propEq('a', 4))(xs) //=> undefined
*/
export const findLastIndex: Curry2<Predicate1, any[], number> = curryN(2, dispatched)
22 changes: 22 additions & 0 deletions fromPairs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import curryN from './utils/curry_n.ts'
import { Curry1 } from './utils/types.ts'

export type Pair<T = any> = [string | number, T]

function _fromPairs<T>(pairs: Pair<T>[]) {
const result: {
[key: string]: T
} = {}
pairs.forEach(p => {
result[p[0]] = p[1]
})

return result
}
/**
* Creates a new object from a list key-value pairs. If a key appears in
* multiple pairs, the rightmost pair is included in the object.
*
* Fae.fromPairs([['a', 1], ['b', 2], ['c', 3]]); //=> {a: 1, b: 2, c: 3}
*/
export const fromPairs: Curry1<Pair[], ReturnType<typeof _fromPairs>> = curryN(1, _fromPairs)
8 changes: 8 additions & 0 deletions mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ export { addIndex } from './addIndex.ts'
export { adjust } from './adjust.ts'
export { all } from './all.ts'
export { always } from './always.ts'
export { any } from './any.ts'
export { ap } from './ap.ts'
export { aperture } from './aperture.ts'
export { append } from './append.ts'
export { assoc } from './assoc.ts'
export { assocPath } from './assocPath.ts'
Expand All @@ -42,10 +44,15 @@ export { dropLastWhile } from './dropLastWhile.ts'
export { dropRepeats } from './dropRepeats.ts'
export { dropRepeatsWith } from './dropRepeatsWith.ts'
export { dropWhile } from './dropWhile.ts'
export { endsWith } from './endsWith.ts'
export { equals } from './equals.ts'
export { filter } from './filter.ts'
export { find } from './find.ts'
export { findIndex } from './findIndex.ts'
export { findLast } from './findLast.ts'
export { findLastIndex } from './findLastIndex.ts'
export { flip } from './flip.ts'
export { Pair, fromPairs } from './fromPairs.ts'
export { identity } from './identity.ts'
export { inc } from './inc.ts'
export { insert } from './insert.ts'
Expand Down Expand Up @@ -91,6 +98,7 @@ export { subtract } from './subtract.ts'
export { sum } from './sum.ts'
export { tail } from './tail.ts'
export { take } from './take.ts'
export { takeLast } from './takeLast.ts'
export { tap } from './tap.ts'
export { transduce } from './transduce.ts'
export { trim } from './trim.ts'
Expand Down
80 changes: 80 additions & 0 deletions specs/any.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { describe, it } from "./_describe.ts"
import {
any,
pipe,
map,
transduce,
flip,
inc,
} from '../mod.ts'
import { eq } from "./utils/utils.ts"


describe('any', () => {
const odd = (a: number) => (a & 1) === 1
const T = () => true
// const intoArray = R.into([])

it('should return true if any element satisfies the predicate', () => {
eq(any(odd, [2, 4, 6, 8, 10, 11, 12]), true)
})

it('should return false if all elements fails to satisfy the predicate', () => {
eq(any(odd, [2, 4, 6, 8, 10, 12]), false)
})

// it('should return true into array if any element satisfies the predicate', () => {
// eq(intoArray(any(odd), [2, 4, 6, 8, 10, 11, 12]), [true])
// })

// it('returns false if all elements fails to satisfy the predicate', () => {
// eq(intoArray(any(odd), [2, 4, 6, 8, 10, 12]), [false])
// })

it('should work with more complex objects', () => {
const people = [
{first: 'Paul', last: 'Grenier'},
{first:'Mike', last: 'Hurley'},
{first: 'Will', last: 'Klein'}
]
const alliterative = (person: typeof people[number]) => person.first.charAt(0) === person.last.charAt(0)

eq(any(alliterative, people), false)
people.push({first: 'Scott', last: 'Sauyet'})
eq(any(alliterative, people), true)
})

it('can use a configurable function', () => {
const teens = [
{name: 'Alice', age: 14},
{name: 'Betty', age: 18},
{name: 'Cindy', age: 17}
]
const atLeast = (age: number) => (person: typeof teens[number]) => person.age >= age

eq(any(atLeast(16), teens), true)
eq(any(atLeast(21), teens), false)
})

it('should return false for an empty list', () => {
eq(any(T, []), false)
})

// it('returns false into array for an empty list', () => {
// eq(intoArray(any(T), []), [false])
// })

it('should work with transformers too', () => {
const arr = [1, 2, 3, 4, 5, 6, 7, 8]
const less2 = (a: number) => a < 2
const t1 = pipe(
map(inc),
any(less2)
)

eq(t1(arr), false)
eq(transduce(t1, flip((a: number, b: number) => a), 11, arr), 2)

})

})
42 changes: 42 additions & 0 deletions specs/aperture.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { describe, it } from "./_describe.ts"
import {
aperture,
pipe,
append,
transduce,
flip,
} from '../mod.ts'
import { eq } from "./utils/utils.ts"


describe('aperture', () => {
const arr = [1, 2, 3, 4, 5, 6, 7]
it('should creates a list of n-tuples from a list', () => {
eq(aperture(1, arr), [[1], [2], [3], [4], [5], [6], [7]])
eq(aperture(2, arr), [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7]])
eq(aperture(3, arr), [[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6], [5, 6, 7]])
eq(aperture(4, [1, 2, 3, 4]), [[1, 2, 3, 4]])
})

it('should returns an empty list when `n` > `list.length`', () => {
eq(aperture(6, [1, 2, 3]), [])
eq(aperture(1, []), [])
})

it('should act as a transducer', () => {
const t1 = pipe(
aperture(2)
)

eq(t1(arr), [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7]])
eq(transduce(t1, flip(append), [], arr), [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7]])

const t2 = pipe(
aperture(8)
)

eq(t2(arr), [])
eq(transduce(t2, flip(append), [], arr), [])
})

})
37 changes: 37 additions & 0 deletions specs/endsWith.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { describe, it } from "./_describe.ts"
import { endsWith } from '../mod.ts'
import { eq } from "./utils/utils.ts"

describe('startsWith', () => {
it('should return true when a string ends with the provided value', () => {
eq(endsWith('c', 'abc'), true)
})

it('should return true when a long string ends with the provided value', () => {
eq(endsWith('ology', 'astrology'), true)
})

it('should return false when a string does not end with the provided value', () => {
eq(endsWith('b', 'abc'), false)
})

it('should return false when a long string does not end with the provided value', () => {
eq(endsWith('olog', 'astrology'), false)
})

it('should return true when an array ends with the provided value', () => {
eq(endsWith(['c'], ['a', 'b', 'c']), true)
})

it('should return true when an array ends with the provided values', () => {
eq(endsWith(['b', 'c'], ['a', 'b', 'c']), true)
})

it('should return false when an array does not end with the provided value', () => {
eq(endsWith(['b'], ['a', 'b', 'c']), false)
})

it('should return false when an array does not end with the provided values', () => {
eq(endsWith(['a', 'b'], ['a', 'b', 'c']), false)
})
})
Loading

0 comments on commit d879264

Please sign in to comment.