У меня есть массив JSON, как показано ниже
[
{"Name" : "Arrow",
"Year" : "2001"
},
{"Name" : "Arrow",
"Type" : "Action-Drama"
},
{ "Name" : "GOT",
"Type" : "Action-Drama"
}
]
и я пытаюсь преобразовать это в
[
{
"Name" : "Arrow",
"Year" : "2001",
"Type" : "Action-Drama",
},
{
"Name" : "GOT",
"Type" : "Action-Drama"
}
]
Любая помощь очень ценится.
Спасибо.
Вы можете использовать reduce()
и findIndex()
let data = [
{"Name" : "Arrow",
"Year" : "2001"
},
{"Name" : "Arrow",
"Type" : "Action-Drama"
},
{ "Name" : "GOT",
"Type" : "Action-Drama"
}
]
let res = data.reduce((ac,a) => {
let ind = ac.findIndex(x => x.Name === a.Name);
ind === -1 ? ac.push({...a}) : ac[ind] = {...ac[ind],...a};
return ac;
},[])
console.info(res)
Вы можете использовать метод Array#reduce
.
let data = [{
"Name": "Arrow",
"Year": "2001"
},
{
"Name": "Arrow",
"Type": "Action-Drama"
},
{
"Name": "GOT",
"Type": "Action-Drama"
}
]
let res = data.reduce((obj, { Name, ...rest }) => {
// define property(key as Name) if not defined
obj[Name] = obj[Name] || { Name };
// copy rest properties to object
Object.assign(obj[Name], rest);
// return object reference
return obj;
// set initial value as epty object
}, {})
// or one liner solution
// let res = data.reduce((obj, { Name, ...rest }) => (obj[Name] = {... obj[Name] || {Name}, ...rest },obj), {})
// now res holds an object where key id name
// get values as an array using Object.values method
console.info(Object.values(res))
С традиционным циклом for с дополнительным объектом, который хранит ссылку на каждый элемент с Name
в качестве ключа.
let data = [{
"Name": "Arrow",
"Year": "2001"
},
{
"Name": "Arrow",
"Type": "Action-Drama"
},
{
"Name": "GOT",
"Type": "Action-Drama"
}
]
// initialize array for result
let res = [],
// an object for array value reference by name
ref = {};
// iterate over main array
for (let i = 0; i < data.length; i++) {
// check property defined in refeence object(Name)
// if not then define and pushj it to result array
if (!(data[i].Name in ref)) res.push(ref[data[i].Name] = {});
// copy propety to object
Object.assign(ref[data[i].Name], data[i]);
}
console.info(Object.values(res))
Можно ли обойтись обычной for
итерацией? Я просто хочу понять.
@rɑːdʒɑ : да, возможно...
Можете ли вы помочь мне понять, как это может быть достижимо?
@rɑːdʒɑ : обновление
Пожалуйста, попробуйте это
var object1 = {
apple: 0,
banana: { weight: 52, price: 100 },
cherry: 97
};
var object2 = {
banana: { price: 200 },
durian: 100
};
// Merge object2 into object1, recursively
$.extend( true, object1, object2 );
console.info( JSON.stringify( object1 ) );
Ссылка:
http://researchhubs.com/post/computing/javascript/merge-content-of-objects.html
ОП не упомянул, что он использует jQuery. Кроме того, хотя это объединяет объекты, это не решает проблему, с которой сталкивается OP: объединение объектов, которые являются внутри одного массива.
Используйте reduce
и Object.assign
, чтобы объединить элементы внутри массива:
const data = [{
"Name" : "Arrow",
"Year" : "2001"
}, {
"Name" : "Arrow",
"Type" : "Action-Drama"
}, {
"Name" : "GOT",
"Type" : "Action-Drama"
}];
function mergeByProp (prop, xs) {
return xs.reduce((acc, x) => {
if (!acc[x[prop]]) {
acc[x[prop]] = x;
} else {
acc[x[prop]] = Object.assign(acc[x[prop]], x);
}
return acc;
}, {});
}
function objToArr (obj) {
return Object.keys(obj).map(key => obj[key]);
}
console.info(objToArr(mergeByProp('Name', data)));
Создайте словарь (просто пустой объект) и используйте значение или ваше свойство «Имя» в качестве ключа. Затем используйте
Object.assign()
, чтобы объединить элементы.