Если у меня есть следующее:
{
prop: "X",
something: "Apple"
},
{
prop: "X",
something: "Apple"
},
{
prop: "Y",
something: "Banana"
},
{
prop: "Y",
something: "Banana"
}
Как я могу превратить это в новый объект, который будет выглядеть примерно так?
{
prop: "X",
apple: 2
},
{
prop: "Y",
banana: 2
}
Вы можете использовать подход одного цикла с закрытием ocer хэш - таблицы для сбора объектов с одной и той же prop
ключа.
var data = [{ prop: "X", something: "Apple" }, { prop: "X", something: "Apple" }, { prop: "Y", something: "Banana" }, { prop: "Y", something: "Banana" }],
result = data.reduce(function (hash) {
return function (r, a) {
var k2 = a.something.toLowerCase();
if (!hash[a.prop]) {
hash[a.prop] = { prop: a.prop };
hash[a.prop][k2] = 0;
r.push(hash[a.prop]);
}
hash[a.prop][k2]++;
return r;
};
}(Object.create(null)), []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
С большим количеством свойств для подсчета
var data = [{ prop: "X", something: "Apple", somethingElse: "Orange" }, { prop: "X", something: "Apple" }, { prop: "Y", something: "Banana" }, { prop: "Y", something: "Banana" }],
result = data.reduce(function (hash) {
return function (r, o) {
if (!hash[o.prop]) {
hash[o.prop] = { prop: o.prop };
r.push(hash[o.prop]);
}
Object.keys(o).forEach(function (k) {
var k2 = o[k].toLowerCase();
if (k !== 'prop') {
hash[o.prop][k2] = (hash[o.prop][k2] || 0) + 1;
}
});
return r;
};
}(Object.create(null)), []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Array.prototype.reduce
может быть полезным здесь:
let data = [{
prop: "X",
something: "Apple"
},
{
prop: "X",
something: "Apple"
},
{
prop: "Y",
something: "Banana"
},
{
prop: "Y",
something: "Banana"
}];
let newData = data.reduce((prev, curr) => {
prev[curr.prop] = prev[curr.prop] || {};
let lowercaseKey = curr.something.toLowerCase();
prev[curr.prop][lowercaseKey] = prev[curr.prop][lowercaseKey] ? prev[curr.prop][lowercaseKey] + 1 : 1;
prev[curr.prop].prop = curr.prop;
return prev;
}, {});
newData = Object.keys(newData).map(key => newData[key]);
console.log(newData);
В принципе, он использует объект в качестве аккумулятора (последний аргумент функции уменьшения), чтобы отслеживать общие значения для каждого элемента в массиве (это полезно, а не просто сразу же нажимать на новый массив, потому что сначала необходимо выполнить итерацию через новый массив для каждой итерации функции reduce
чтобы найти, существует ли объект или нет). Затем, наконец, мы снова повторяем все ключи нового объекта и получаем значения.
Pro-tip: проще понять, если вы играете с фрагментом кода выше и регистрируете значения во время каждой итерации.