Как объединить два массива JavaScript объектов JSON без использования JQUERY?

У меня есть два массива объектов (если я не использую правильную терминологию, простите меня. Я новичок в JS). Массивы dataset и dataset2 имеют объекты с общим ключом id. Я хочу объединить каждый объект, чтобы сформировать новый массив объединенных объектов. Как показано в datasetCombined ниже.

dataset = [{​
    "State": "AL",
    "id": 1000,
    "name": "Alabama",​​
    "percent_educated": 24},

    {​
    "State": "AL",
    "id": 1001,
    "name": "Autauga County",​​
    "percent_educated": 24.6},

    {​
    "State": "AL",
    "id": 1003,
    "name": "Baldwin County",​​
    "percent_educated": 29.5
    }]

dataset2 = [{​
    "id": 1000,
    "qualified_professionals": "64,767,787",​​
    "high_school": "58,820,411",
    "middle_school_or_lower": "27,818,380" },

    {
    "id": 1001,
    "qualified_professionals": "783,076",​​
    "high_school": "1,009,593",
    "middle_school_or_lower": "496,036" },

    {​
    "id": 1003,
    "qualified_professionals": "8,968",​​
    "high_school": "12,519",
    "middle_school_or_lower": "4,528" 
    }]

Желаемый результат:

datasetCombined = [{​
    "State": "AL",
    "id": 1000,
    "name": "Alabama",​​
    "percent_educated": 24,
    "qualified_professionals": "64,767,787",​​
    "high_school": "58,820,411",
    "middle_school_or_lower": "27,818,380"},

    {​
    "State": "AL",
    "id": 1001,
    "name": "Autauga County",​​
    "percent_educated": 24.6,
    "qualified_professionals": "783,076",​​
    "high_school": "1,009,593",
    "middle_school_or_lower": "496,036"},

    {​
    "State": "AL",
    "id": 1003,
    "name": "Baldwin County",​​
    "percent_educated": 29.5,
    "qualified_professionals": "8,968",​​
    "high_school": "12,519",
    "middle_school_or_lower": "4,528"
    }]
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
294
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Попробуйте это с Underscore.js или Лодаш

var mergedList = _.map(dataset1, function(item){
  return _.extend(item, _.findWhere(dataset2, { 
    id: item.id 
  })); 
});

Вы должны указать, что используется сторонняя библиотека и какая именно.

Alexander Staroselsky 05.10.2018 18:36

Принято к сведению. Спасибо @alexander

Midhun G S 05.10.2018 18:38

Вы можете использовать Array.prototype.reduce:

const datasetCombined = dataset1.reduce((acc, next) => {
    const combinedItem = Object.assign(
        {},
        next,
        dataset2.find(item => (item.id = next.id))
    );
    acc.push(combinedItem);
    return acc;
}, []);

Вы можете найти id и добавить существующий объект или отправить копию объекта в набор результатов.

Это работает для произвольного количества массивов.

var dataset = [{ State: "AL", id: 1000, name: "Alabama", percent_educated: 24 }, { State: "AL", id: 1001, name: "Autauga County", percent_educated: 24.6 }, { State: "AL", id: 1003, name: "Baldwin County", percent_educated: 29.5 }],
    dataset2 = [{ id: 1000, qualified_professionals: "64,767,787", high_school: "58,820,411", middle_school_or_lower: "27,818,380" }, { id: 1001, qualified_professionals: "783,076", high_school: "1,009,593", middle_school_or_lower: "496,036" }, { id: 1003, qualified_professionals: "8,968", high_school: "12,519", middle_school_or_lower: "4,528" }],
    result = [dataset, dataset2].reduce((r, a) => {
        a.forEach(o => {
            var temp = r.find(({ id }) => o.id === id);
            if (!temp) {
                r.push(Object.assign({}, o));
            } else {
                Object.assign(temp, o);
            }
        });
        return r;
    }, []);
    
console.info(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Немного лучший подход с Map.

var dataset = [{ State: "AL", id: 1000, name: "Alabama", percent_educated: 24 }, { State: "AL", id: 1001, name: "Autauga County", percent_educated: 24.6 }, { State: "AL", id: 1003, name: "Baldwin County", percent_educated: 29.5 }],
    dataset2 = [{ id: 1000, qualified_professionals: "64,767,787", high_school: "58,820,411", middle_school_or_lower: "27,818,380" }, { id: 1001, qualified_professionals: "783,076", high_school: "1,009,593", middle_school_or_lower: "496,036" }, { id: 1003, qualified_professionals: "8,968", high_school: "12,519", middle_school_or_lower: "4,528" }],
    result = Array.from([dataset, dataset2].reduce(
        (r, a) => a.reduce((m, o) => m.set(o.id, Object.assign(m.get(o.id) || {}, o)), r),
        new Map
    ).values());
    
console.info(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Возможное решение указанной выше проблемы:

Object.assign(b, a);

Таким образом, b будет иметь как свои собственные свойства, так и свойства a '. Однако мы могли бы избежать изменения b. В таком случае мы можем ввести новый пустой объект и скопировать в него свойства из a и b.

const c = Object.assign({}, a, b);

И если по какой-то причине вы не можете использовать языковые функции ES6 в своем приложении, вы можете прибегнуть к использованию библиотеки Lodash.

const c = _.assign({}, a, b);

когда я вывожу это в console.info, я получаю Object {}, могу ли я как-нибудь получить обратно массив объектов []?

DeeeeRoy 05.10.2018 18:55

Я попробовал то же самое в консоли браузера Chrome и получил результат. Попробуйте следующие фрагменты кода: const a = {name: "John", age: 23}; const b = {работа: "Аналитик"}; const c = Object.assign ({}, a, b); введите c в консоли, и вы получите результат как {имя: "Джон", возраст: 23, должность: "Аналитик"}

Arvind Mishra 06.10.2018 10:59
Ответ принят как подходящий

После ошибки с неправильным прочтением вашего вопроса я потратил немного времени и построил этот пример для вас, чтобы объединить два массива на основе Id.

let dataset = [{
    "State": "AL",
    "id": 1000,
    "name": "Alabama",
    "percent_educated": 24
  },
  {
    "State": "AL",
    "id": 1001,
    "name": "Autauga County",
    "percent_educated": 24.6
  },
  {
    "State": "AL",
    "id": 1003,
    "name": "Baldwin County",
    "percent_educated": 29.5
  }
];

let dataset2 = [{
    "id": 1000,
    "qualified_professionals": "64,767,787",
    "high_school": "58,820,411",
    "middle_school_or_lower": "27,818,380"
  },
  {
    "id": 1001,
    "qualified_professionals": "783,076",
    "high_school": "1,009,593",
    "middle_school_or_lower": "496,036"
  },
  {
    "id": 1003,
    "qualified_professionals": "8,968",
    "high_school": "12,519",
    "middle_school_or_lower": "4,528"
  }
];

// create a function to reduce your arrays
let reducer = function(accumulator, currentValue, currentIndex, array) {
   // check if the item already exists in the array
	let found = accumulator.find((item) => item.id == currentValue.id);
  
  if (found) {
    // if it exists then use assign to merge the two values
    Object.assign(found, currentValue)
  } else {
    // doesn't exist, just add it to the array
  	accumulator.push(currentValue);
  }
  
  return accumulator;
}

let datasetCombined = [];

dataset.reduce(reducer, datasetCombined);
dataset2.reduce(reducer, datasetCombined);

console.info(datasetCombined);

Если вы не используете ES6 и не хотите использовать какую-либо библиотеку, например Lodash, и Если количество объектов в обоих массивах одинаково и они упорядочены по свойству id (как показано в вашем примере), вы можете использовать приведенный ниже код:

var datasetCombined = [];

dataset.map(function(obj,keyNo){
  for (var key in dataset2[keyNo]){
    obj[key]=dataset2[keyNo][key];
  }
  datasetCombined.push(obj)
});

Другие вопросы по теме