import concatMap from '../array/concatMap.js'
import identity from './identity.js'
/**
* @name addIndex
* @function
* @since v0.11.2
* @category Function
* @sig
* ((a … → b) … → [a] → *) → ((a …, Int, [a] → b) … → [a] → *)
* @description Creates a new function to iterate through an array, the provided function should be one that accepts a higher order function (such as reduce, filter, or map). It will then attach the index to the provided function upon calling it.
* @param {Function} fn The original function to add the index and list onto
* @return {Function} A new function that will come with the index and full list attached.
* @example
* import { addIndex, filter, map, reduce } from 'kyanite'
* const m = addIndex(map)
* const f = addIndex(filter)
* const r = addIndex(reduce)
* const data = ['f', 'o', 'o', 'b', 'a', 'r']
*
* m((x, i) => `${x}-${i}`, data) // => ['f-0', 'o-1', 'o-2', 'b-3', 'a-4', 'r-5']
* f((_, i) => i > 2, data) // => ['b', 'a', 'r']
* r((val, acc, i) => acc.concat(val + i), [], data) // => ['f0', 'o1', 'o2', 'b3', 'a4', 'r5']
*/
const addIndex = fn => (...args) => {
let idx = 0
const [origFn] = args
const list = args[args.length - 1]
const copiedArgs = args.slice()
copiedArgs[0] = (...innerArgs) => {
const result = origFn(...concatMap(identity, [innerArgs, [idx, list]]))
idx += 1
return result
}
return fn(...copiedArgs)
}
export default addIndex