Как объединить пары ключ-значение двух массивов json? - JavaScript - PullRequest
0 голосов
/ 17 января 2019

У меня есть два массива JSON, как это. Я хочу объединить их пары ключевых значений. Это некоторые предметы, которые встречаются в обоих случаях, в то время как они являются необычными.

var jsonData1 = [
  {
    firstName: "Sam",
    age: "10"
  },
  {
    firstName: "John",
    age: "11"
  },
  {
    firstName: "Jack",
    age: "12"
  },
  {
    firstName: "Pam",
    age: "13"
  },
  {
    firstName: "Tom",
    age: "14"
  },
  {
    firstName: "Mitch",
    age: "15"
  }
];

var jsonData2 = [
      {
        firstName: "Sam",
        city: "London"
      },
      {
        firstName: "John",
        city: "New York"
      },
      {
        firstName: "Jack",
        city: "Paris"
      },
      {
        firstName: "Pam",
        city: "Moscow"
      },
      {
        firstName: "Roger",
        city: "Shanghai"
      },
      {
        firstName: "Don",
        city: "Jakarta"
      }
    ];

Как вы можете найти firstName в первом массиве, который не имеет города во втором массиве. Опять же, во втором массиве есть имя firstName, у которого нет города в первом массиве.

Мне нужно объединить эти 2 массива в один массив, если firstName не имеет возраста или города, ему будет назначено '' (пустая строка).

В новом массиве будет 3 поля, есть несколько элементов, которые будут иметь значения в 2 полях. Они имеют одно поле в виде пустой строки.

Я хочу сделать это с помощью Vanilla JS, я не хочу использовать Jquery, Lodash и Underscore.

Ответы [ 3 ]

0 голосов
/ 17 января 2019

Один из возможных подходов:

const jsonData1=[{firstName:"Sam",age:"10"},{firstName:"John",age:"11"},{firstName:"Jack",age:"12"},{firstName:"Pam",age:"13"},{firstName:"Tom",age:"14"},{firstName:"Mitch",age:"15"}];
const jsonData2=[{firstName:"Sam",city:"London"},{firstName:"John",city:"New York"},{firstName:"Jack",city:"Paris"},{firstName:"Pam",city:"Moscow"},{firstName:"Roger",city:"Shanghai"},{firstName:"Don",city:"Jakarta"}];

const result = [].concat(jsonData1, jsonData2).reduce((acc, ele) => {
        const existing = acc.find(x => x.firstName === ele.firstName);
        if(!existing) return acc.concat({firstName: ele.firstName, city: ele.city || '', age: ele.age || ''});
        Object.keys(ele).forEach(x => existing[x] = ele[x]);
        return acc;
    },[])
    
console.log(result);
0 голосов
/ 17 января 2019

Я понимаю, что вы уже приняли ответ, но я решила, что могу предложить альтернативу, лучше или хуже.

var jsonData1 = [{firstName: "Sam",age: "10"},{firstName: "John",age: "11"},{firstName: "Jack",age: "12"},{firstName: "Pam",age: "13"},{firstName: "Tom",age: "14"},{firstName: "Mitch",age: "15"}];
var jsonData2 = [{firstName: "Sam",city: "London"},{firstName: "John",city: "New York"},{firstName: "Jack",city: "Paris"},{firstName: "Pam",city: "Moscow"},{firstName: "Roger",city: "Shanghai"},{firstName: "Don",city: "Jakarta"}];

var defaults = {firstName: "", age: "", city: ""};
var data  = [ ...jsonData1, ...jsonData2 ];
var names = [ ...new Set(data.map(i=>i.firstName)) ];

var res = names.map(n => data
                  .reduce((acc, jd) => jd.firstName === n ? {...acc, ...jd} : acc, defaults)
                );

console.log(res);

var data объединяет два массива данных в один, используя расширенный синтаксис (литералы массива) .

var names создает массив уникальных имен, используя Set.

map() выполняет итерации по списку имен, создавая один объединенный объект для каждого. Это объединение выполняется с использованием reduce() и синтаксиса распространения (литералы объекта) .

0 голосов
/ 17 января 2019

Есть несколько способов приблизиться к этому, однако один из вариантов будет основывать это на методе Array#reduce() следующим образом:

const jsonData1=[{firstName:"Sam",age:"10"},{firstName:"John",age:"11"},{firstName:"Jack",age:"12"},{firstName:"Pam",age:"13"},{firstName:"Tom",age:"14"},{firstName:"Mitch",age:"15"}];
const jsonData2=[{firstName:"Sam",city:"London"},{firstName:"John",city:"New York"},{firstName:"Jack",city:"Paris"},{firstName:"Pam",city:"Moscow"},{firstName:"Roger",city:"Shanghai"},{firstName:"Don",city:"Jakarta"}];


/* 
Use Array#concat() to combine both input arrays before performing
the merge. This will ensure that all items in both arrays are
processed and accounted for during the merge (which is important in
situations where the input arrays differ in length).

Object.values() is used to transform the dictionary resulting from
reduce() to an array
*/
var result = Object.values(
[].concat(jsonData1, jsonData2
).reduce((dict, item) => {

  /* 
  We use Array#reduce is an intermediate step to construct a dictionary
  which maps each unique "item.firstName" to a corresponding object 
  that contains the merged (or yet to be merged) data for this first 
  name
  */
   
  var value = dict[item.firstName] || {}

  /*
  Use Object.assign() to merge existing data for "item.firstName" with
  current item being processed. Also pass default values as first
  argument to ensure all three key values are present in merge result
  */
  value = Object.assign({ firstName : '', age : '', city : ''} , value, item)

  /*
  Update the dictionary with merged data
  */
  dict[item.firstName] = value

  return dict

}, {}))

console.log(result);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...