import get from 'lodash-es/get.js'
import size from 'lodash-es/size.js'
import treeObj from './treeObj.mjs'
import isestr from './isestr.mjs'
import isarr from './isarr.mjs'
import isobj from './isobj.mjs'
import isobj0 from './isobj0.mjs'
/**
* 展平樹狀物件或陣列
*
* Unit Test: {@link https://github.com/yuda-lyu/wsemi/blob/master/test/flattenTree.test.mjs Github}
* @memberOf wsemi
* @param {Array|Object} data 輸入樹狀物件或陣列
* @param {Object} [opt={}] 輸入設定物件,預設{}
* @param {String} [bindKey='id'] 輸入節點物件識別用欄位字串,預設'id'
* @param {String} [bindChildren='children'] 輸入節點物件內存放子節點欄位字串,預設'children'
* @returns {Array} 回傳節點物件陣列
* @example
*
* let obj = {
* id: 1,
* data: '1-abc',
* children: [
* {
* id: 2,
* data: '2-def',
* },
* {
* id: 3,
* data: '3-ghi',
* children: [
* {
* id: 4,
* data: '4-jkl',
* },
* ],
* },
* {
* id: 5,
* data: '5-mno',
* },
* ],
* }
* let crobj = flattenTree(obj)
* console.log(JSON.stringify(crobj))
* // => {"id":1,"data":"1-abc","children":[{"id":2,"data":"2-def"},{"id":3,"data":"3-ghi","children":[{"id":4,"data":"4-jkl"}]},{"id":5,"data":"5-mno"}],"level":0,"nk":[0]}
*
* let arr = [
* {
* id: 1,
* text: '1x',
* },
* {
* id: 2,
* text: '2y',
* children: [
* {
* id: 3,
* text: '3z',
* },
* ],
* },
* {
* id: 4,
* text: 'empty',
* },
* ]
* let crarr = flattenTree(arr)
* console.log(JSON.stringify(crarr))
* // => [{"id":1,"text":"1x","level":0,"nk":[0]},{"id":2,"text":"2y","children":[{"id":3,"text":"3z"}],"level":0,"nk":[1]},{"id":3,"text":"3z","level":1,"nk":[1,"children",0]},{"id":4,"text":"empty","level":0,"nk":[2]}]
*
*/
function flattenTree(data, opt = {}) {
//check
if (isarr(data)) {
if (data.length === 0) {
return []
}
}
else if (isobj(data)) {
if (isobj0(data)) {
return []
}
}
else {
return []
}
//bindKey
let bindKey = get(opt, 'bindKey', null)
if (!isestr(bindKey)) {
bindKey = 'id'
}
//bindChildren
let bindChildren = get(opt, 'bindChildren', null)
if (!isestr(bindChildren)) {
bindChildren = 'children'
}
//data
let toArr = false
if (isobj(data)) {
toArr = true
data = [data]
}
function getNk(nk) {
//將nk內插入bindChildren, 因主節點為array, 各節點內的子節點也為array
let r = [nk[0]]
for (let i = 1; i < nk.length; i++) {
let k = nk[i]
r.push(bindChildren)
r.push(k)
}
return r
}
//nodes
let nodes = []
treeObj(data, (value, key, nk) => {
//console.log({ value, key, nk })
//pk
let pk = get(value, bindKey, null)
//children
let children = get(value, bindChildren, null)
//push
if (pk) {
let nkt = getNk([...nk, key])
nodes.push({
...value,
level: (size(nkt) - 1) / 2,
nk: nkt,
// key,
})
if (children) {
return children
}
}
})
//toArr
if (toArr) {
nodes = nodes[0]
}
return nodes
}
export default flattenTree