UNPKG

yylib-quick-mobile

Version:

yylib-quick-mobile

117 lines (115 loc) 4.67 kB
/*树结构数据的相关操作工具方法*/ function getChildrenlength(children) { let len = 1; if (Array.isArray(children)) { len = children.length; } return len; } function getSiblingPosition(index, len, siblingPosition) { if (len === 1) { siblingPosition.first = true; siblingPosition.last = true; } else { siblingPosition.first = index === 0; siblingPosition.last = index === len - 1; } return siblingPosition; } var TreeUtils = { /** * 遍历树结构子集对象 * @param childs {array} 需要遍历的树结构 * @param callback {function} 遍历时的回调函数,传递参数:item(当前结点)、index(当前索引)、pos(当前层级和索引)、key、siblingPos(兄弟节点间的索引)、parent * @param parent {object} 当前父级节点 */ loopAll:function(childs, callback, parent) { const loop = (children, level, _parent) => { const len = getChildrenlength(children); children.forEach((item, index) => { const pos = `${level}-${index}`; if(item){ if (item.children&&item.children.constructor==Array) { loop(item.children, pos, { node: item, pos }); } callback(item, index, pos, item.key || pos, getSiblingPosition(index, len, {}), _parent); } }); }; loop(childs, 0, parent); } /** * 查找树节点下指定节点属性值匹配的节点 * @param nodes {array} 子节点集合 * @param propName {string} 属性名 * @param propValue {*} 属性值 * @param loop{boolean} 默认:true,是否递归遍历子集合 * @param only{boolean} 默认:true,是否匹配到第一个就终止 * @param childPropName{boolean} 默认:children,子节点集合的属性名 */ ,findWithPropName:function(nodes,propName,propValue,loop,only,childPropName){ var _results = []; var _nodes =(nodes&&nodes.constructor==Array)?nodes:[]; var _childPropName = childPropName?childPropName:'children'; for(var i=0;i<_nodes.length;i++){ var node = _nodes[i]; if(!node||typeof node!="object")continue; if(node[propName]&&node[propName]==propValue){ _results.push(node); if(only==undefined||only==true)break; } if(loop!=false&&node[_childPropName]&&node[_childPropName].length>0){ var currResults = this.findWithPropName(node[_childPropName],propName,propValue,loop,only,_childPropName); if(currResults!=null){ _results=_results.concat(currResults); } } } return _results; } /** * 移除树节点下指定节点属性值匹配的节点 * @param tree {object} 子节点集合 * @param propName {string} 属性名 * @param propValue {*} 属性值 * @param loop{boolean} 默认:true,是否递归遍历子集合 * @param childName 子集合的属性名 */ ,removeWithPropName:function(tree,propName,propValue,loop,childName="children"){ const doLoop = (data,propName,propVal, callback) => { data.forEach((item, index, arr) => { if (item[propName] === propVal) { return callback(item, index, arr); } if (loop!=false&&(item[childName]&&item[childName].constructor==Array)) { return doLoop(item[childName],propName,propVal, callback); } }); }; if(tree && propName && propValue){ doLoop((tree&&tree.constructor==Array)?tree:[tree],propName, propValue, function (item, index, arr) { arr.splice(index, 1); }); } return tree; } /** * 通过ID查找树节点 * @param nodes {array} 子节点集合 * @param idValue {*} ID属性值 */ ,findById:function(nodes,idValue){ var results = this.findWithPropName(nodes,'id',idValue,true,true); return results.length>0?results[0]:null; } /** * 删除树下对应ID的节点 * @param tree {object} 树结构对象 * @param nodeId {*} 树节点id */ ,removeById:function(tree,nodeId){ var tree = this.removeWithPropName(tree,'id',nodeId,true); return tree; } } module.exports = TreeUtils;