获取指定链路对应对象的引用
当遇到要在循环过程中,要从另一个json对象内找到与之匹配的数据,并把当前循环的数据作为匹配json数据的子项。以下内容可以做个参考。
适用场景
现在有两份数据,需要对两份数据进行拼接。
一份数据是一维数组,另一份数据是多层级的对象。
其中一维数组的每项都有一个指向多层对象链路地址,现在的要求是返回当前链路地址对应的对象。
示例效果
js
// 列表
const list = [
{
name: 'yuanyang',
namespaces: ['henan', 'xinxiang']
},
{
name: 'zhongguancun',
namespaces: ['beijing', 'haidian']
},
]
// 省份集合
const provinceCollection = [{
name: 'henan',
children: [{
name: 'xinxiang',
children: []
}]
},
{
name: 'beijing',
children: [{
name: 'haidian',
children: []
}]
}]
// 期望输出
[{
name: 'henan',
children: [{
name: 'xinxiang',
children: [{
name: 'yuanyang',
children: []
}]
}]
},
{
name: 'beijing',
children: [{
name: 'haidian',
children: [{
name: 'zhongguancun',
children: []
}]
}]
}]
设计思路
像这种不确定层级但格式相同的数据,经常的处理方式就是递归。
而在递归过程中如何能找到末级节点,这里面是使用了数组的shift方法,当每找到当前数据后,需要修改namespaces的下次查找值。
完整代码
js
/**
* 递归获取指定地址空间
* @param {array} dataSource - 目标对象
* @param {array} namespaces - 链路信息
* @returns {object} - 命中的对象,由于js引用类型的原因,所以这里可以直接修改源数据
*/
const getAddress = (dataSource, namespaces = [...targetPath]) => {
const currentNamespace = namespaces.shift(); // 每次都取最新的查找值
const currentItem = dataSource.find(item => item.name === currentNamespace);
if (currentItem?.children.length) {
return getAddress(currentItem?.children, namespaces);
}
return currentItem;
}
看下使用效果:
js
// 列表
const list = [
{
name: 'yuanyang',
namespaces: ['henan', 'xinxiang']
},
{
name: 'zhongguancun',
namespaces: ['beijing', 'haidian']
},
]
// 省份集合
const provinceCollection = [{
name: 'henan',
children: [{
name: 'xinxiang',
children: []
}]
},
{
name: 'beijing',
children: [{
name: 'haidian',
children: []
}]
}]
list.forEach(item => {
const currentCity = getAddress(provinceCollection, item.namespaces);
if (currentCity) {
currentCity.children.push({
name: item.name,
children: []
})
}
})
console.log('provinceCollection------:', JSON.stringify(provinceCollection));
// => [{"name":"henan","children":[{"name":"xinxiang","children":[{"name":"yuanyang","children":[]}]}]},{"name":"beijing","children":[{"name":"haidian","children":[{"name":"zhongguancun","children":[]}]}]}]