import _curry2 from '../_internals/_curry2.js'
import _appendǃ from '../_internals/_appendǃ.js'
import _assocǃ from '../_internals/_assocǃ.js'
import _reduce from '../_internals/_reduce.js'
/**
* @name groupBy
* @function
* @since v0.2.1
* @category Array
* @sig (a -> String) -> [a] -> { String: [a] }
* @description Groups values of an array based on the function passed in
* @param {Function} fn The function to run our values through
* @param {Array} list The array to go through
* @return {Object} An object with the grouped values
*
* @example
* import { groupBy } from 'kyanite'
*
* groupBy(Math.floor, [4.2, 6.1, 6.4]) // => { '4': [4.2], '6': [6.1, 6.4] }
*
* // It's also curried
*
* const g = groupBy(Math.floor)
*
* g([4.2, 6.1, 6.4]) // => { '4': [4.2], '6': [6.1, 6.4] }
*/
const groupBy = (fn, list) =>
_reduce((v, acc) => {
const k = fn(v)
const _an = _assocǃ(acc, k)
return Object.prototype.hasOwnProperty.call(acc, k) ? _an(_appendǃ(acc[k], v)) : _an([v])
}, {}, list)
export default _curry2(groupBy)