import { isFunction, isObjTag } from '../../is'
import curry from '../../fp/curry'
import keys from '../../util/keys'
import preAllocate from '../../array/preAllocate'
import reduce from './_reduce'
interface Functor<Value> {}
interface MapFunction<FunctorWithValue, ReturnValue> {
(fn: FunctorWithValue): ReturnValue
}
function _map<FunctorWithValue, ReturnValue>(
fn: FunctorWithValue,
functorList: MapFunction<FunctorWithValue, ReturnValue>
): ReturnValue[] {
let idx = 0
const len = functorList.length
const result = preAllocate(len)
while (idx < len) {
result[idx] = fn(functorList[idx])
idx += 1
}
return result
}
/**
* @desc `while (index < list.length) push fn(list[index++])`
* @name _map
* @alias baseMaps
* @since 5.0.0-beta.1
* @memberOf loop
*
* {@link https://github.com/ramda/ramda/blob/master/src/internal/_map.js ramda-_map}
* @see {@link ramda-_map}
*
* @param fn function to apply
* @param functorList function/list
*/
function map<FunctorWithValue, ReturnValue>(
fn: FunctorWithValue,
functor:
| MapFunction<FunctorWithValue, ReturnValue>
| MapFunction<FunctorWithValue, ReturnValue>[]
): ReturnValue[] {
if (isFunction(functor)) {
return curry(functor.length, function(this: any) {
return fn.call(this, functor.apply(this, arguments))
})
} else if (isObjTag(functor)) {
return reduce(
(acc: any, key: string | symbol | number) => {
acc[key] = fn(functor[key])
return acc
},
{},
keys(functor)
)
} else {
return _map(fn, functor)
}
}
export default map