import get from 'lodash-es/get.js'
import size from 'lodash-es/size.js'
import isEqual from 'lodash-es/isEqual.js'
import isearr from './isearr.mjs'
import isfun from './isfun.mjs'
import isbol from './isbol.mjs'
/**
* 找尋陣列內元素指定值
*
* Unit Test: {@link https://github.com/yuda-lyu/wsemi/blob/master/test/arrReduce.test.mjs Github}
* @memberOf wsemi
* @param {Array} vall 輸入原始陣列
* @param {Function} fun 輸入處理與比對函數,輸入參數為全域暫存值與現在提取值,函數比對完須回傳新的全域暫存值
* @param {Object} [opt={}] 輸入設定物件,預設{}
* @param {Boolean} [opt.returnIndex=false] 輸入是否回傳排序指標陣列布林值,預設false
* @returns {Number|Object} 回傳指定值數字或判斷具有指定值之物件
* @example
*
* let r
*
* r = arrReduce([100000, 1, 30, 4, 21], (vTemp, vNow) => {
* if (vTemp === null) {
* return vNow
* }
* return Math.min(vTemp, vNow)
* })
* console.log(r)
* // => 1
*
* r = arrReduce([1, 30, 4, 21, 100000], (vTemp, vNow) => {
* if (vTemp === null) {
* return vNow
* }
* return Math.max(vTemp, vNow)
* })
* console.log(r)
* // => 100000
*
* r = arrReduce([1, 30, 4, 100000, 21], (vTemp, vNow) => {
* if (vTemp === null) {
* return vNow
* }
* return Math.max(vTemp, vNow)
* }, { returnIndex: true })
* console.log(r)
* // => 3
*
* r = arrReduce(
* [{ s: 'March', i: 1 }, { s: 'Jan', i: 4 }, { s: 'Feb', i: 100000 }, { s: 'Dec', i: 30 }, { s: 'Nov', i: 25, }],
* (vTemp, vNow) => {
* if (vTemp === null) {
* return vNow.i
* }
* return Math.min(vTemp, vNow.i)
* },
* )
* console.log(r)
* // => 1
*
* r = arrReduce(
* [{ s: 'March', i: 1 }, { s: 'Jan', i: 4 }, { s: 'Feb', i: 100000 }, { s: 'Dec', i: 30 }, { s: 'Nov', i: 25, }],
* (vTemp, vNow) => {
* if (vTemp === null) {
* return vNow
* }
* return vTemp.i < vNow.i ? vNow : vTemp //max
* },
* )
* console.log(r)
* // => { s: 'Feb', i: 100000 }
*
* r = arrReduce(
* [{ s: 'March', i: 1 }, { s: 'Jan', i: 4 }, { s: 'Feb', i: 100000 }, { s: 'Dec', i: 30 }, { s: 'Nov', i: 25, }],
* (vTemp, vNow) => {
* if (vTemp === null) {
* return vNow
* }
* return vTemp.i < vNow.i ? vNow : vTemp //max
* },
* { returnIndex: true }
* )
* console.log(r)
* // => 2
*
*/
function arrReduce(vall, fun, opt = {}) {
//check
if (!isearr(vall)) {
return null
}
if (!isfun(fun)) {
return null
}
//returnIndex
let returnIndex = get(opt, 'returnIndex')
if (!isbol(returnIndex)) {
returnIndex = false
}
//find
let ind = -1
let vv = null
for (let k = 0; k < size(vall); k++) {
//v
let v = vall[k]
//fun
let r = fun(vv, v)
//update
if (!isEqual(vv, r)) {
vv = r
ind = k
}
}
//returnIndex
let r = null
if (returnIndex) {
r = ind
}
else {
r = vv
}
return r
}
export default arrReduce