合并数组JS中的对应对象

时间:2020-01-28 13:06:52

标签: javascript arrays object

如何合并两个对象数组,其中一个数组中的一个对象与另一个数组中的一个对象相对应。不对应的对象应保留。 iduid是相应条件。

const data1 = [{
  id: 1,
  someKey1: 'someValue2'
}, {
  id: 2,
  someKey2: 'someValue2'
}, {
  id: 3,
  someKey3: 'someValue3'
}]
const data2 = [{
  uid: 1,
  someKey4: 'someValue4'
}, {
  uid: 2,
  someKey5: 'someValue5'
}]

// expected result:

[{
  someKey1: 'someValue2',
  someKey4: 'someValue4'
}, {
  someKey2: 'someValue2',
  someKey5: 'someValue5',
  {
    id: 3,
    someKey3: 'someValue3'
  }
}]

6 个答案:

答案 0 :(得分:3)

您可以从两组数组中获取所有id和uid,然后将它们放入一组,然后将其转回数组以获取唯一id / uid的列表。然后,您可以为两个数组创建映射。映射id / uid以保存其相应的对象属性。然后,使用唯一的ID / UID数组,您可以List<Destination> destination = new ArrayList<>(); destination.add(new Destination("lat")); newOrderRequest.setDestinations(destination); 将每个ID import java.util.ArrayList; 中保存到其对应的对象,如下所示:

.map()

创建集合的主要原因是,如果Map没有对象的ID,则const data1 = [{ id: 1, someKey1: 'someValue2'}, { id: 2, someKey2: 'someValue2' }, { id: 3, someKey3: 'someValue3' }] const data2 = [{ uid: 1, someKey4: 'someValue4'}, { uid: 2, someKey5: 'someValue5' }]; const getMap = (arr, id) => new Map(arr.map(({[id]:_id, ...r}) => [_id, {...r}])); const ids = [...new Set(data1.map(({id}) => id).concat(data2.map(({uid}) => uid)))]; const data1Map = getMap(data1, 'id'); const data2Map = getMap(data2, 'uid'); const result = ids.map(id => ({...(data1Map.get(id) || {}), ...(data2Map.get(id) || {})})); console.log(result);的对象将被保留。

答案 1 :(得分:0)

您可以创建一个对数据数组进行迭代的函数,并将其对象放入索引为iduid的新数组中。

const data1 = [{ id: 1, someKey1: 'someValue2'}, { id: 2, someKey2: 'someValue2' }, { id: 3, someKey3: 'someValue3' }]
const data2 = [{ uid: 1, someKey4: 'someValue4'}, { uid: 2, someKey5: 'someValue5' }]

let result = [];
result = mergeIntoResult(result, data1, "id");
result = mergeIntoResult(result, data2, "uid");

console.log(JSON.stringify(result));

function mergeIntoResult(resultArray, dataArray, idProperty) {
    return dataArray.reduce((acc,curr) => {
      const index = curr[idProperty];
      acc[index] = acc[index] || {}; //Take existing object or create default
      acc[index] = {...acc[index], ...curr}; //Insert object data
      delete acc[index][idProperty]; //Delete the "id" or "uid" field from the new object
      return acc;
    }, resultArray);
}

答案 2 :(得分:0)

尝试以下代码:

let data1 = [{
  id: 1,
  someKey1: 'someValue2'
}, {
  id: 2,
  someKey2: 'someValue2'
}, {
  id: 3,
  someKey3: 'someValue3'
}]
let data2 = [{
  uid: 1,
  someKey4: 'someValue4'
}, {
  uid: 2,
  someKey5: 'someValue5'
}]

let result = [];

data1.forEach((obj, i) => {
  const targetValues = data2.filter(x => x.uid === obj.id);
  result[i] = obj;

  if (targetValues && targetValues.length) {
    delete obj.id;
    targetValues.forEach(value => {
      delete value.uid;
      result[i] = {...result[i], ...value};
    })
    data2 = data2.filter(x => x.uid !== obj.id);
  }
});
result = result.concat(data2);
console.log(result);

答案 3 :(得分:0)

这是另一种方法,该方法未对性能进行优化,并且不如其他答案那么简洁,但细分了步骤以明确正在发生的事情。

const data1 = [{ id: 1, someKey1: 'someValue2'}, { id: 2, someKey2: 'someValue2' }, { id: 3, someKey3: 'someValue3' }]
const data2 = [{ uid: 1, someKey4: 'someValue4'}, { uid: 2, someKey5: 'someValue5' }]

function mergeProperties(set1, linkingProperty1, set2, linkingProperty2){

  const keys1 = set1.map( item => item[linkingProperty1] );
  const keys2 = set2.map( item => item[linkingProperty2] );
  const mergedKeys = keys1.concat(keys2);
  const filteredKeys = mergedKeys.filter( key => !!key || key === 0); //truthy or actually number 0
  const uniqueKeys = filteredKeys.filter((a, b) => filteredKeys.indexOf(a) === b);

  // now we have a complete list, with no duplicates, of all possible ids

  const mergedArray = uniqueKeys.reduce( (accumulator, key) => {
      const resultInSet1 = set1.find( item => item[linkingProperty1] === key );
      const resultInSet2 = set2.find( item => item[linkingProperty2] === key );
      let item = {};
      if(resultInSet1){
        delete resultInSet1[linkingProperty1];
        item = {...resultInSet1};
      }
      if(resultInSet2){
        delete resultInSet2[linkingProperty2];
        item = {...item, ...resultInSet2};
      }
      return [...accumulator, item];
  }, []);

  return mergedArray;
}

console.log( mergeProperties(data1,"id",data2,"uid") );

答案 4 :(得分:0)

您可以使用purchases.uuid功能。此外,您可以使用map集合来访问Map的项目:

O(1)

一个例子:

const createObj = (fooObj, keyToFilter) => {
  if (fooObj)
    return Object.fromEntries(Object.entries(fooObj).filter(([k, v])=> k != keyToFilter ));
  return null;
}    

const result = data1.map(s=> ({...createObj(s,'id'), ...createObj(maps.get(s.id),'uid')}));

答案 5 :(得分:0)

这是一个可以满足您需要的功能:

const objectMerge = (sourceData, joinData) => 
  sourceData.map(item => {
    const { id, ...restOfItem } = item
    const foundJoins = joinData.filter(obj => obj.uid === id)
    if (foundJoins.length === 0) {
      return item
    }
    const dataFromJoins = foundJoins.reduce((result, join) => { 
      // Return everything in the object except the UID
      const { uid, ...restOfFields } = join
      return Object.assign({}, result, restOfFields)
    }, {})
    return Object.assign({}, restOfItem, dataFromJoins)
  })

您可以看到它在这里工作:https://repl.it/@RobBrander/Object-Merger

相关问题