#javascript #arrays #object
#javascript #массивы #объект
Вопрос:
У меня есть такая структура JSON:
const arr = [
{
id: "TaskStatuses",
rows: [
{id: "1", name: "Success"},
{id: "2", name: "Error"},
]
},
{
id: "Objects",
rows: [
{id: "1", name: "Object1"},
{id: "2", name: "Object2"},
]
},
{
id: "Groups",
rows: [
{id: "1", name: "Group1"},
{id: "2", name: "Group2"},
]
},
]
Мне нужно создать массив с некоторым условием. Если мое условие правильно, я буду нажимать элементы arr.rows.
Наконец, я хочу получить эту структуру:
[
{
Objects: "Object1",
Groups: "Group1"
},
{
Objects: "Object2",
Groups: "Group2"
}
]
Я пытаюсь сделать так
let sites = []
for (let el in arr) {
if (arr.id == "Objects") {
for (let item of el.rows) {
sites.push({Objects: item.name})
}
}
if (arr.id == "Groups") {
for (let item of el.rows) {
sites.push({Groups: item.name})
}
}
Комментарии:
1. Вы пытаетесь сгруппировать записи на
arr
основе их идентификатора? Как{id: "1", name: "Object1"}
сопоставляется запись с{id: "1", name: "Group1"}
таким образом, чтобы они оказались в одном объекте{ Objects: "Object1", Groups: "Group1" }
?2. Да, вы правы. Группировка по идентификатору.
Ответ №1:
Основываясь на комментариях и упомянутом вами ожидаемом конечном массиве объектов, я немного изменил вашу логику, чтобы она соответствовала ожидаемому результату.
Мой подход использует дополнительное пространство, но время o (nlogn) (не уверен, что это наиболее эффективно). Надеюсь, этот код поможет.
let firstArr = [], secondArr = [];
arr.forEach((d, i) => {
if (d.id === "Objects") {
firstArr.push(...d.rows);
}
if (d.id === "Groups") {
secondArr.push(...d.rows);
}
});
//console.log(firstArr, secondArr);
//sorting, if necessary based on id of each arr[i].rows
firstArr.sort(function (a, b) {
return a.id - b.id || a.name.localeCompare(b.name);
});
//sorting, if necessary based on id of each arr[i].rows
secondArr.sort(function (a, b) {
return a.id - b.id || a.name.localeCompare(b.name);
});
let index = 0,
size = Math.min(firstArr.length, secondArr.length);
let finalArr = [];
for (index; index < size; index ) {
if (firstArr[index].id === secondArr[index].id) {
finalArr.push({
Objects: firstArr[index].name,
Groups: secondArr[index].name,
});
}
}
//console.log(finalArr); ////this is your final Array.
Ответ №2:
Вместо построения построения массива, создание объекта значительно упростило бы задачу. Вы можете использовать ключ id
as для каждого объекта, чтобы вы могли легко найти объект, к которому хотите присоединить свойства.
Приведенный ниже фрагмент перебирает разные «столбцы». Если столбец соответствует критериям (является либо «Объектами», либо «Группами»), мы пройдемся по строкам столбца и добавим свойства к результирующему объекту.
const arr = [{
id: "TaskStatuses",
rows: [
{id: "1", name: "Success"},
{id: "2", name: "Error"},
]
}, {
id: "Objects",
rows: [
{id: "1", name: "Object1"},
{id: "2", name: "Object2"},
]
}, {
id: "Groups",
rows: [
{id: "1", name: "Group1"},
{id: "2", name: "Group2"},
]
}];
const sites = {};
const whitelist = new Set(["Objects", "Groups"]);;
for (const column of arr) {
if (!whitelist.has(column.id)) continue;
for (const row of column.rows) {
sites[row.id] ||= {};
sites[row.id][column.id] = row.name;
}
}
console.log(sites);