Как я могу пройти и сократить объект?

1

Если у меня есть следующее:

{
    prop: "X",
    something: "Apple"
},
{
    prop: "X",
    something: "Apple"    
},
{
    prop: "Y",
    something: "Banana"
},
{
    prop: "Y",
    something: "Banana"
}

Как я могу превратить это в новый объект, который будет выглядеть примерно так?

{
    prop: "X",
    apple: 2
},
{
    prop: "Y",
    banana: 2
}
Теги:
object

2 ответа

0
Лучший ответ

Вы можете использовать подход одного цикла с закрытием 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; }
  • 0
    Это действительно здорово. Как я могу разместить для третьего имущества? Как если бы у меня было: {prop: "X", что-то: "Apple", что-тоElse: "FruitX"}
  • 0
    Пожалуйста, предоставьте пример данных и вывод.
Показать ещё 1 комментарий
1

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: проще понять, если вы играете с фрагментом кода выше и регистрируете значения во время каждой итерации.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню