// https://github.com/lodash/lodash/blob/master/toArray.js
import { isStringPrimitive } from '../../primitive/string/isStringPrimitive'
import { isIterator } from '../../iterator/check/isIterator'
import { isNil } from '../../primitive/nil'
import { isMap, isSet } from '../../collection'
import isArray from '../check/isArray'
import ArrayFrom from './toArrayFrom'
/**
* @desc anything into an array
* @memberOf cast
* @name toArr
* @alias toArray
*
* @sig * => Array
* @since 0.0.1
*
* @param {any} ar turn this into an array
* @return {Array} anything into an array
*
* @tests deps/to-arr
* @types deps
*
* {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L465 underscore-to-arr}
* @see {@link underscore-to-arr}
*
* @example
*
* toarr([])
* //=> []
*
* toarr('')
* //=> ['']
*
* toarr('1,2')
* //=> ['1', '2']
*
* toarr('1,2')
* //=> ['1', '2']
*
* const map = new Map()
* map.set('eh', true)
* const arr = toarr(map.entries())
* //=> ['eh', true]
*
* const set = new Set()
* set.add('eh')
* set.add(true)
* const arr = toarr(map.entries())
* //=> ['eh', true]
*
* toarr('').concat(toarr(false)).concat(toarr(null))
* //=> ['', false, null]
*
*/
const toArray = <Value = Map<any, any> | { [key: string]: any }>(
ar: Value
): Array<Value> | string[] => {
// @NOTE: !'' === true
if (isStringPrimitive(ar)) return ar.includes(',') ? ar.split(',') : [ar]
else if (isNil(ar)) return []
else if (isArray(ar)) {
// else if (!ar) return [ar]
return ar
} else if (isSet(ar) || isMap(ar) || (ar as any).values) {
// hasIn(ar, 'values')
/**
* @desc when using `new Set().values`... no forEach o.o
* @NOTE .values is also on `Object`...
*/
return ArrayFrom((ar as any).values(ar))
} else if (isIterator(ar)) return ArrayFrom(ar)
else return [ar]
}
export default toArray