Ответ 1
Разделите все элементы массива на новые массивы: те, у которых полный атрибут component
(а не только число), и те, у кого нет. Прокрутите оставшиеся исходные элементы, которые должны иметь только числовые атрибуты component
, затем найдите соответствующий @componentID
из "хорошего" массива и сделайте некоторое копирование и перемещение.
// initialize some vars
var final = [], temp = [], bad = [],
c = {},
computers = [
{
"@computerID": 1,
"component": {
"@componentID": 2,
"processor": 2,
"ram": "8g",
"harddrive": "wd"
}
},
{
"@computerID": 3,
"component": 2
}
];
// split original array into 3: final, bad, & temp
while(computers.length > 0) {
c = computers.pop();
if (c.hasOwnProperty("component")) {
if (typeof c.component === "number") {
temp.push(c);
} else {
final.push(c);
}
} else {
bad.push(c);
}
}
// loop through temp & look up @componentID within final
while (temp.length > 0) {
c = temp.pop();
// should @componentID be 1-of-a-kind?
var found = getObjects(final, "@componentID", c.component);
if (found.length) {
c.component = found[0];
final.push(c);
} else {
bad.push(c);
}
}
// SOURCE: http://stackoverflow.com/a/4992429/1072176
function getObjects(obj, key, val) {
var objects = [];
for (var i in obj) {
if (!obj.hasOwnProperty(i)) continue;
if (typeof obj[i] == 'object') {
objects = objects.concat(getObjects(obj[i], key, val));
} else if (i == key && obj[key] == val) {
objects.push(obj);
}
}
return objects;
}
// should result in just one or two populated arrays: final and/or bad
alert(JSON.stringify(final));
Вы заметите, что я на самом деле сделал три массива, но только два в конечном итоге заселены: final
имеет ваши хорошие новые объекты, а другой (bad
) является объектом catch-all для объектов без атрибута компонента, или для номера компонента которого соответствующий @componentID не может быть найден.