import { inArray, isNaN, isString, isArray, isFunction } from './is.js'
/**
* @template T
* @param {T} value
* @param {number} [count]
* @returns {T[]}
*/
export function createArray(value, count = 1) {
return [].fill.call(new Array(count), value)
}
/**
* @param {any[]} a
* @param {any[]} b
* @returns {any[]}
*/
export function unionArray(a, b) {
return a.concat(b.filter(v => !inArray(v, a)))
}
/**
* @param {any[]} a
* @param {any[]} b
* @returns {any[]}
*/
export function interArray(a, b) {
return a.filter(v => b.includes(v))
}
/**
* @param {any[]} a
* @param {any[]} b
* @returns {any[]}
*/
export function diffArray(a, b) {
return a.filter(v => !b.includes(v))
}
/**
* @param {any[]} a
* @param {any[]} b
* @returns {any[]}
*/
export function compArray(a, b) {
const diffa = diffArray(a, b)
const diffb = diffArray(b, a)
return diffa.concat(diffb)
}
/**
* @param {any[]} arr
* @param {string} [prop] unique by which property
* @returns {any[]}
*/
export function uniqueArray(arr, prop) {
const exists = []
return arr.filter((item) => {
if (prop) {
let value = item[prop]
if (exists.includes(value)) {
return false
}
else {
exists.push(value)
return true
}
}
else {
if (exists.includes(item)) {
return false
}
else {
exists.push(item)
return true
}
}
})
}
/**
* @param {any[]} items
* @param {string} [by] which property sort by
* @param {boolean} [decs]
* @returns {any[]}
*/
export function sortArray(items, by, decs = false) {
const res = [].concat(items)
res.sort((a, b) => {
let oa = by ? a[by] : a
let ob = by ? b[by] : b
oa = !isNaN(+oa) ? +oa : isString(oa) ? oa : 10
ob = !isNaN(+ob) ? +ob : isString(ob) ? ob : 10
if (oa < ob) {
return decs ? 1 : -1
}
if (oa === ob) {
return 0
}
if (oa > ob) {
return decs ? -1 : 1
}
})
return res
}
/**
* @param {any} arr
* @returns {any[]}
*/
export function toArray(arr) {
return Array.from(arr)
}
/**
* @param {any[][]} arr
* @returns {any[]}
*/
export function flatArray(arr) {
const res = []
arr.forEach((item) => {
const items = isArray(item) ? item : [item]
res.push(...items)
})
return res
}
/**
* slice an array into [count] sub-array
* @param {any[]} arr
* @param {number} count
* @returns {array[]}
*/
export function groupArray(arr, count) {
const results = []
arr.forEach((item, i) => {
const index = parseInt(i / count)
results[index] = results[index] || []
results[index].push(item)
})
return results
}
/**
* split an array to sevral
* @param {any[]} arr
* @param {*|function} splitter
* @returns {array[]}
* @ts_declare function splitArray(arr: any[], split: any | ((item: any, i: number) => boolean)): any[]
*/
export function splitArray(arr, splitter) {
const results = []
let temp = []
arr.forEach((item, i) => {
if (splitter === item || (isFunction(splitter) && splitter(item, i))) {
results.push(temp)
temp = []
}
else {
temp.push(item)
if (i === arr.length - 1) {
results.push(temp)
}
}
})
return results
}
/**
* @param {any[][]} arr
* @param {any} join
* @returns {any[]}
*/
export function joinArray(arr, join) {
const results = []
arr.forEach((items, i) => {
if (i < arr.length - 1) {
results.push(...items, join)
}
else {
results.push(...items)
}
})
return results
}