Объединить два массива Json при условии в lodash - PullRequest
0 голосов
/ 05 июня 2018

У меня есть Two Json Array Like

var a = [{_id:1, name: "Bhavin"},{_id:2, name: "Raj"},{_id:3, name: "Rahul"}];    
var b = [{_id:1, post: "Developer"},{_id:2, post: "Quality Analyst"}];

Теперь я хочу объединить Like:

var c = [{_id:1, name: "Bhavin", post: "Developer"},{_id:2, name: "Raj", post: "Quality Analyst"},{_id:3, name: "Rahul"}];

Я знаю, что могу легко сделать это в Plain Javascript, используя два дляцикл ... Но это занимает n * n времени.

Я хочу решить эту проблему только за n раз.

Как мне этого добиться?

Ответы [ 4 ]

0 голосов
/ 06 июня 2018

Вы можете легко решить эту проблему, сопоставив массив меньшего размера в составленный объект ключ-значение, где ключи объекта - это идентификаторы, а их значения - сами связанные значения.Как только связь будет завершена, мы можем выполнить итерацию и преобразовать массив большего размера, назначив недостающие значения из сопоставленного объекта.

// ensure that b has more items than a
// to prevent data loss
if(a.length > b.length) {
  var t = b;
  b = a;
  a = t;
}

// create an object composed of of ids as key associated with each object.
// a loash alternative is: 
// var map = _.keys(a, '_id');
var map = a.reduce((r, v) => (r[v._id] = v, r), {});

// assign missing properties from each object from the associated mapped object.
var result = b.map(v => ({...map[v._id], ...v}));

var a = [{_id:1, name: "Bhavin"},{_id:2, name: "Raj"},{_id:3, name: "Rahul"}];
var b = [{_id:1, post: "Developer"},{_id:2, post: "Quality Analyst"}];

// ensure that b has more items than a
// to prevent data loss
if(a.length > b.length) {
  var t = b;
  b = a;
  a = t;
}

// create an object composed of of ids as key associated with each object.
// a loash alternative is: 
// var map = _.keys(a, '_id');
var map = a.reduce((r, v) => (r[v._id] = v, r), {});

// assign missing properties from each object from the associated mapped object.
var result = b.map(v => ({...map[v._id], ...v}));

console.log(result);
.as-console-wrapper{min-height:100%;top:0}
0 голосов
/ 05 июня 2018

Вы должны использовать функцию lodash mergeWith.

var a = [{_id:1, name: "Bhavin"},{_id:2, name: "Raj"},{_id:3, name: "Rahul"}];

var b = [{_id:1, post: "Developer"},{_id:2, post: "Quality Analyst"}];


// ouput [{_id:1, name: "Bhavin", post: "Developer"},{_id:2, name: "Raj", post: "Quality Analyst"},{_id:3, name: "Rahul"}];

function customizer(firstValue, secondValue) {
  return Object.assign({}, firstValue, secondValue);
}

console.log(_.mergeWith(a, b, customizer));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>
0 голосов
/ 05 июня 2018

Привет, вы можете достичь этого с помощью кода ниже

_.map(a, function (el){
   return _.merge(el , _.find(b, {_id: el._id }))
})

// using chain, i would prefer first it looks clean :-p
_.chain(a).map(function (o){
   return _.merge(o, _.find(b, {_id: o._id }))
})
.value()

Я попробую это с цепочкой и обновлю ответ

0 голосов
/ 05 июня 2018

Вполне возможно достичь этого простым Javascript за O(n) время:

var a = [{_id:1, name: "Bhavin"},{_id:2, name: "Raj"},{_id:3, name: "Rahul"}];
var b = [{_id:1, post: "Developer"},{_id:2, post: "Quality Analyst"}];

const aById = a.reduce((map, { _id, name }) => map.set(_id, name), new Map());
const bById = b.reduce((map, { _id, post }) => map.set(_id, post), new Map());
const combined = [...aById.entries()].map(([_id, name]) => {
  const person = { _id, name };
  const post = bById.get(_id);
  if (post) person.post = post;
  return person;
});

console.log(combined);
var c = [{_id:1, name: "Bhavin", post: "Developer"},{_id:2, name: "Raj", post: "Quality Analyst"},{_id:3, name: "Rahul"}];

Map с гарантированно имеют O(1) время поиска.Хеш-карты объектов (например, {'1': 'Developer', '2': 'Quality Analyst'}) - нет.

У вас было несколько опечаток в исходном коде, я предполагаю, что они были непреднамеренными - я исправил их в приведенном выше фрагменте кода.

...