Как консолидировать массив объектов - PullRequest
1 голос
/ 03 октября 2019

У меня есть массив объектов, и я пытаюсь объединить объекты. Я пытаюсь создать функцию, которая принимает список в качестве аргумента и возвращает новый объект.

function mergeValues(list) {
    var obj = {};
    list.forEach(item => {
        if (!obj[item.state]) {
            obj[item.state] = Object.assign({}, Object.keys(obj));
        } else {
            obj[item.state] = obj[item.state] + item.population;
        }
    });
    return obj;
}

Текущий вход

var list = [
  { state: 'NJ', city: 'Newark', population: 150 },
  { state: 'NJ', city: 'Trenton', population: 200 },
  { state: 'NY', city: 'New York City', population: 500 },
  { state: 'MI', city: 'Detroit', population: 200 },
  { state: 'MI', city: 'Lansing', population: 100 }
];

Требуемый выход

var obj = {
  MI: { count: 2, city: ['Detroit', 'Lansing'], population: 300 },
  NJ: { count: 2, city: ['Newark', 'Trenton'], population: 350 },
  NY: { count: 1, city: ['New York City'], population: 500 }
};

Редактировать: Это то, как я начал, и застрял. Ключ возвращается с состоянием, но значения переопределяются самым последним объектом.

function mergeValues(list) {
  var obj = {};

  list.forEach(item => {
    obj[item.state] = Object.assign({}, item);
  });

  return obj;
}

Ответы [ 2 ]

1 голос
/ 03 октября 2019

С помощью Reduction легко выйти.

function transform(list) {
    return list.reduce((latestState, { state, city, population }) => {
        const isNewEntry = !(state in latestState);
        if(isNewEntry){
            latestState[state] = {
                count: 1,
                city: [city],
                population: population
            }
        }else{
            latestState[state] = {
                count: latestState[state].count + 1,
                city: [...latestState[state].city, city],
                population: latestState[state].population + population
            }
        }
        return latestState;
    }, {});
}

Итак, что здесь происходит.

С помощью Reduc мы перебираем список и каждый новый цикл получаем последнее состояние, в этом примеремы начинаем с пустого объекта.

Далее мы проверяем, требуется ли создание записи или обновление (существует). На основе isNewEntry мы создаем или обновляем запись.

https://codesandbox.io/s/amazing-ellis-mh4b6

1 голос
/ 03 октября 2019

Вы можете использовать Object.fromEntries для создания отображения состояния / объекта, а затем выполнить итерацию исходного списка для агрегирования количества, города и населения:

function mergeValues(list) {
    let obj = Object.fromEntries(list.map(({state}) => 
                  [state, { count: 0, city: [], population: 0 }]
    ));
    list.forEach(({state, city, population}) => {
        obj[state].count++;
        obj[state].city.push(city);
        obj[state].population += population; 
    });
    return obj;
}

var list = [{ state: 'NJ', city: 'Newark', population: 150 },{ state: 'NJ', city: 'Trenton', population: 200 },{ state: 'NY', city: 'New York City', population: 500 },{ state: 'MI', city: 'Detroit', population: 200 },{ state: 'MI', city: 'Lansing', population: 100 }];
console.log(mergeValues(list));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...