如何通过使用键,值对将它们合并为一个数组来合并具有两种不同大小的两个对象数组?

问题描述 投票:0回答:4

我有两个以JSON格式查找的对象数组:

   {
  "Arr1":
   [
    { "_id": "firstSub1", "count": 1, "price": 4 },
    { "_id": "firstSub2", "count": 2, "price": 7 },
    { "_id": "firstSub3", "count": 3, "price": 1 }
    { "_id": "firstSub4", "count": 4, "price": 1 }
   ],

    "Arr2":
     [
      { "name": "firstSub1", "date": 05 / 20 / 1998, "type": sometype1 },
      { "name": "firstSub2"  "date": 12 / 22 / 2011, "type": sometype2 },
      { "name": "firstSub3", "date": 09 / 23 / 2004, "type": sometype3 }
      { "name": "firstSub9", "date": 09 / 23 / 2004, "type": sometype9 }
    ]
//Desired Output
    "finalArray":
     [
      { "name": "firstSub1", "date": 05 / 20 / 1998, "type": sometype1, "count": 1, "price": 4 },  
      { "name": "firstSub2"  "date": 12 / 22 / 2011, "type": sometype2, "count": 2, "price": 7 },
      { "name": "firstSub3", "date": 09 / 23 / 2004, "type": sometype3, "count": 3, "price": 1 },
      { "name": "firstSub9", "date": 09 / 23 / 2004, "type": sometype9 },
      { "_id": "firstSub4", "count": 4, "price": 1 }
          ]   

}

我需要比较第一个数组中的_id,看看是否与Arr2中的name匹配,如果_id === name匹配它们。

我尝试过使用lodash及其不需要的内容,并映射函数如下:

  mergeArray() {
    .... //pulling data

    let Arr1 = data['Arr1Data'];
    let Arr2 = data['Arr2Data'];

    let finalArray = Arr2.map((e, _) =>
      (_ = Arr1.find((q) => e.name === q._id)) ?
        { ...e, ..._ } : e)
    console.log(finalArray)
  }

来自Arr2的所有数据都回来并且仅与Arr1的一半数据合并我的数据没有返回所需的输出...我如何映射这两个数组并具有联合和交集?

javascript angular typescript lodash
4个回答
1
投票

使用vanilla Js,你可以从两个数组中获得一个独特的_idname数组,循环遍历它并从迭代中匹配当前id的两个数组中加入对象:

扣除了ids和names的数组:

const ids = [...new Set([...Arr1.map(e => e._id), ...Arr2.map(e => e.name)])];

循环以连接两个数组中的元素:

const result = ids.map(e => ({
  ...Arr1.find(o => o._id === e),
  ...Arr2.find(o => o.name === e)
}))

const Arr1 = [{"_id": "firstSub1","count": 1,"price": 4},{"_id": "firstSub2","count": 2,"price": 7},{"_id": "firstSub3","count": 3,  "price": 1}, {"_id": "firstSub4","count": 4,"price": 1}];

const Arr2 = [{"name": "firstSub1","date": "05 / 20 / 1998","type": "sometype1"}, {"name": "firstSub2","date": "12 / 22 / 2011","type": "sometype2"}, {"name": "firstSub3","date": "09 / 23 / 2004","type": "sometype3"}, {"name": "firstSub9","date": "09 / 23 / 2004","type": "sometype9"}];

const ids = [...new Set([...Arr1.map(e => e._id), ...Arr2.map(e => e.name)])];

const result = ids.map(e => ({
  ...Arr2.find(o => o.name === e),
  ...Arr1.find(o => o._id === e)
}))
console.log(result)

编辑:您可以在.map()中调整返回的对象以删除属性(如_id):

const Arr1 = [{"_id": "firstSub1","count": 1,"price": 4},{"_id": "firstSub2","count": 2,"price": 7},{"_id": "firstSub3","count": 3,  "price": 1}, {"_id": "firstSub4","count": 4,"price": 1}];

const Arr2 = [{"name": "firstSub1","date": "05 / 20 / 1998","type": "sometype1"}, {"name": "firstSub2","date": "12 / 22 / 2011","type": "sometype2"}, {"name": "firstSub3","date": "09 / 23 / 2004","type": "sometype3"}, {"name": "firstSub9","date": "09 / 23 / 2004","type": "sometype9"}];

const ids = [...new Set([...Arr1.map(e => e._id), ...Arr2.map(e => e.name)])];

const result = ids.map(e => {
  const obj = {
    ...Arr2.find(o => o.name === e),
    ...Arr1.find(o => o._id === e)
  }
  
  if(obj.name && obj._id) delete obj._id;
  
  return obj;
})
console.log(result)

0
投票

一种解决方案是使用Array.reduce()开始,accumulator等于Arr2JSON.parse(JSON.stringify(Arr2)))的副本,所以我们不会改变原始数组Arr2。现在,在迭代Arr1时,如果我们找到匹配,那么我们使用Object.assign()将相关属性添加到accumulator上的关联对象,否则我们将整个对象放在accumulator上:

const Arr1 = [
    {"_id": "firstSub1", "count": 1, "price": 4},
    {"_id": "firstSub2", "count": 2, "price": 7},
    {"_id": "firstSub3", "count": 3, "price": 1},
    {"_id": "firstSub4", "count": 4, "price": 1}
];

const Arr2 = [
    {"name": "firstSub1", "date": "05/20/1998", "type": "sometype1"},
    {"name": "firstSub2",  "date": "12/22/2011", "type": "sometype2"},
    {"name": "firstSub3", "date": "09/23/2004", "type": "sometype3"},
    {"name": "firstSub9", "date": "09/23/2004", "type": "sometype9"}
];

let res = Arr1.reduce((acc, {_id, count, price}) =>
{
    let fIdx = acc.findIndex(({name}) => name === _id);

    if (fIdx >= 0)
        Object.assign(acc[fIdx], {count, price});
    else
        acc.push({_id, count, price});
        
    return acc;
}, JSON.parse(JSON.stringify(Arr2)));

console.log(res);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

0
投票

您可以按name排序并比较i + 1索引名称以验证是否应合并i + 1索引和i索引,或者对象是否没有用于合并的对。

例如,按name排序意味着下一个对象/索引将是该对。

[{name: "firstSub1", count: 1}, {name: "firstSub1", date: "dd / mm / yyyy"}] // Pair found

要么

[{name: "firstSub1", count: 1}, {name: "firstSub2", count: 1}] // There is no a pair

这假设有最多一对

let obj = {  "Arr1": [{      "_id": "firstSub1",      "count": 1,      "price": 4    },    {      "_id": "firstSub2",      "count": 2,      "price": 7    },    {      "_id": "firstSub3",      "count": 3,      "price": 1    },    {      "_id": "firstSub4",      "count": 4,      "price": 1    }  ],  "Arr2": [{      "name": "firstSub1",      "date": "05 / 20 / 1998",      "type": "sometype1"    },    {      "name": "firstSub2",      "date": "12 / 22 / 2011",      "type": "sometype2"    },    {      "name": "firstSub3",      "date": "09 / 23 / 2004",      "type": "sometype3"    },    {      "name": "firstSub9",      "date": "09 / 23 / 2004",      "type": "sometype9"    }  ]};

// All objects in one array.
let merge = [...obj.Arr2, 
             // The map is to change _id by name, this is used later.
             ...obj.Arr1.map(({_id, count, price}) => ({name: _id, count, price}))]
                  .sort((a, b) => a.name.localeCompare(b.name));

// This approach doesn't mutate the source objects.
let result = [];
for (let i = 0; i < merge.length;) {
  if (merge[i + 1] && merge[i + 1].name === merge[i].name) {
    result.push(Object.assign(Object.create(null), merge[i], merge[i + 1]));
    i++;
  } else result.push(merge[i]);
  i++;
}

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

0
投票

您可以使用lodash的_.flow()创建一个组合数组的函数,通过name_id(无论在对象上找到什么)对它们进行分组。如果a组包含多个项目,则它将合并为单个对象,并省略_id属性。

const { flow, partialRight: pr, concat, groupBy, map, merge, has, head, omit } = _

const fn = flow(
  concat, // combine to a single array
  pr(groupBy, o => o.name || o._id), // group by the value of name or _id
  pr(map, o => o.length === 1 ? head(o) : _.omit( // if a group contains 2 items merge them, and remove _id
    merge({}, ...o),
    '_id'
  )),
)

const Arr1 = [{"_id": "firstSub1","count": 1,"price": 4},{"_id": "firstSub2","count": 2,"price": 7},{"_id": "firstSub3","count": 3,  "price": 1}, {"_id": "firstSub4","count": 4,"price": 1}]

const Arr2 = [{"name": "firstSub1","date": "05 / 20 / 1998","type": "sometype1"}, {"name": "firstSub2","date": "12 / 22 / 2011","type": "sometype2"}, {"name": "firstSub3","date": "09 / 23 / 2004","type": "sometype3"}, {"name": "firstSub9","date": "09 / 23 / 2004","type": "sometype9"}]

const result = fn(Arr2, Arr1)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
© www.soinside.com 2019 - 2024. All rights reserved.