我有2个阵列A和B:
"A": [{
"name": "test1",
"id": "build:jenkins>test1"
}, {
"name": "test2",
"id": "build:jenkins>test2"
}, {
"name": "maven",
"id": "build:maven"
}, {
"name": "maven1",
"id": "build:maven1"
}]
"B": [{
"name": "jenkins",
"id": "build:jenkins"
}, {
"name": "m1",
"id": "build:maven>m1"
}, {
"name": "m2",
"id": "build:maven>m2"
}, {
"name": "maven3",
"id": "build:maven3"
}]
我试图得到一个结果数组“C”,它将根据“id”搜索两个数组中的可用子节点,并给出一个数组:
"C":
[{ "id": "build:jenkins",
"children":
[{"name": "test1","id": "build:jenkins>test1"},
{"name": "test2","id": "build:jenkins>test2"}
]
},
{ "id": "build:maven",
"children":
[{"name": "m1","id": "build:maven>m1"},
{"name": "m2","id": "build:maven>m2"}
]
},
{"id": "build:maven1","children":[]},
{"id": "build:maven3","children":[]}
]
我试图遍历数组A,然后遍历数组B,根据id访问子节点,但不能同时在两个数组中进行双向搜索。请帮我得到数组C的结果。
答案 0 :(得分:1)
首先,您需要一个实用程序函数,它将按id
找到数组项:
function findArrayItemById(id, inArray) {
var sep = '>'; // change this if you need another separator, can also be regex
for (var i = 0; i < inArray.length; i++) {
if (inArray[i].id === id.split(sep)[0])
return inArray[i];
}
return false;
}
然后是一个函数,它以你需要的格式将多个数组合并为一个:
function buildMergedArray(arrays) {
var result = [],
sep = '>', // change this if you need another separator, can also be regex
found;
for (var i = 0; i < arrays.length; i++) {
for (var j = 0; j < arrays[i].length; j++) {
found = findArrayItemById(arrays[i][j].id, result);
if (found)
found.children.push(arrays[i][j]);
else
result.push({
id: arrays[i][j].id.split('>')[0],
children: []
});
}
}
return result;
}
最后,您将获得所需的C
结果,如下所示:
var result = buildMergedArray([source.A, source.B]);
答案 1 :(得分:0)
具有临时对象和新数组的递归构建的提议。
var object = { "A": [{ "name": "test1", "id": "build:jenkins>test1" }, { "name": "test2", "id": "build:jenkins>test2" }, { "name": "maven", "id": "build:maven" }, { "name": "maven1", "id": "build:maven1" }], "B": [{ "name": "jenkins", "id": "build:jenkins" }, { "name": "m1", "id": "build:maven>m1" }, { "name": "m2", "id": "build:maven>m2" }, { "name": "maven3", "id": "build:maven3" }], C: [] };
void function () {
var temp = {}, PROP = ['id', 'name'];
function split(s) {
return s.split(':').pop().split('>');
}
function f(array) {
array.forEach(function (a) {
var o = temp;
split(a.id).forEach(function (b) {
o[b] = o[b] || {};
o = o[b];
});
o.id = a.id;
o.name = a.name;
});
}
function r(object, array) {
Object.keys(object).filter(function (a) { return !~PROP.indexOf(a); }).forEach(function (k) {
var obj = {};
PROP.forEach(function (a) {
if (a in object[k]) {
obj[a] = object[k][a];
}
});
obj.children = [];
array.push(obj);
if (typeof object[k] === 'object') {
r(object[k], obj.children);
}
});
}
f(object.A);
f(object.B);
r(temp, object.C);
}();
document.write('<pre>' + JSON.stringify(object, 0, 4) + '</pre>');
另一种方法:
孩子们[]正在每个级别创建。是否有可能只在根级别,如问题中的数组C所示。还有可能有一个非递归的解决方案吗?
var object = { "A": [{ "name": "test1", "id": "build:jenkins>test1" }, { "name": "test2", "id": "build:jenkins>test2" }, { "name": "maven", "id": "build:maven" }, { "name": "maven1", "id": "build:maven1" }], "B": [{ "name": "jenkins", "id": "build:jenkins" }, { "name": "m1", "id": "build:maven>m1" }, { "name": "m2", "id": "build:maven>m2" }, { "name": "maven3", "id": "build:maven3" }], C: [] };
void function () {
object.C = [];
Object.keys(object).forEach(function (k) {
object[k].forEach(function (a) {
var path = a.id.split(/[:>]/);
if (path.length === 2) {
a = { id: a.id, children: [] };
object.C.some(function (b) {
if (b.id === path.join(':')) {
return true;
}
}) || object.C.push(a);
return;
}
object.C.some(function (b) {
a = JSON.parse(JSON.stringify(a));
if (b.id === path.slice(0, 2).join(':')) {
b.children = b.children || [];
b.children.some(function (c, i, aa) {
if (c.id === a.id) {
aa[i] = a;
return true;
}
}) || b.children.push(a);
return true;
}
}) || object.C.push({ id: path.slice(0, 2).join(':'), children: [a] });
});
});
}();
document.write('<pre>' + JSON.stringify(object, 0, 4) + '</pre>');