首页 > 解决方案 > 比较两个具有共同字段的数组,然后推送到具有相应分组字段的新数组

问题描述

这里的一般编程问题。

我有这个数组叫SPACES

[
  {
    _id: 5e1c4689429a8a0decf16f69,
    challengers: [
      5dfa24dce9cbc0180fb60226,
      5dfa26f46719311869ac1756,
      5dfa270c6719311869ac1757
    ]
  },
  {
    _id: 5e1c4eb9c9461510407d5e81,
    challengers: [ 5dfa24dce9cbc0180fb60226, 5dfa26f46719311869ac1756 ],
  }
]

这个数组叫做USERS

[
  {
    _id: 5dfa24dce9cbc0180fb60226,
    name: 'Account 1',
    email: 'account1@gmail.com',
    spaces: [ 5e1c4689429a8a0decf16f69, 5e1c4eb9c9461510407d5e81 ],
  },
  {
    _id: 5dfa26f46719311869ac1756,
    name: 'Account 2',
    email: 'account2@gmail.com',
    spaces: [ 5e1c4689429a8a0decf16f69, 5e1c4eb9c9461510407d5e81 ]
  },
  {
    _id: 5dfa270c6719311869ac1757,
    name: 'Account 3',
    email: 'account3@gmail.com',
    spaces: [ 5e1c4689429a8a0decf16f69 ]
  }
]

我想要做的是通过两者,而不是让SPACES.challengers数组只是IDS,我希望数组包含每个USER对象。

例如,如果USER有一个 ID 在SPACES.challengers数组中,则将用户推送到该数组中(这将是整个对象)。

到目前为止,我已经尝试过了(我还不是很好):

 users.map( ( user ) => {
          spaces.map( ( space ) => {
              if ( user.spaces.includes( space._id ) ) {
                       space.challengers.push(user)
                  }
             } );
        } );

但是,我没有进入 IF 块。(即使我这样做了,也不确定它是否会起作用,或者这是否是如何做到的)。做双重地图感觉很奇怪,因为我得到了这么多的迭代,而且它重复了我的推送(因为我没有逻辑来查看它是否刚刚被推送)。

标签: javascriptnode.js

解决方案


假设数组中的每个条目Users都有一个唯一的 ID,我们可以构建一个Hashmap来存储(id, index)对,以便Users在遍历数组时有效地从数组中搜索 ID Spaces

let spaces = [{_id: '5e1c4689429a8a0decf16f69',challengers: ['5dfa24dce9cbc0180fb60226', '5dfa26f46719311869ac1756', '5dfa270c6719311869ac1757']},{_id: '5e1c4eb9c9461510407d5e81',challengers: [ '5dfa24dce9cbc0180fb60226', '5dfa26f46719311869ac1756' ],}]

let users = [{_id: '5dfa24dce9cbc0180fb60226',name: 'Account 1',email: 'account1@gmail.com',spaces: [ '5e1c4689429a8a0decf16f69', '5e1c4eb9c9461510407d5e81' ],},{_id: '5dfa26f46719311869ac1756',name: 'Account 2',email: 'account2@gmail.com',spaces: [ '5e1c4689429a8a0decf16f69', '5e1c4eb9c9461510407d5e81' ]},{_id: '5dfa270c6719311869ac1757',name: 'Account 3',email: 'account3@gmail.com',spaces: [ '5e1c4689429a8a0decf16f69' ]}]

let IDIndexMapping = {} // To store (_id, index) pairs, in order to improve search efficiency

for(let index in users) // Iterate through Users array using index
    IDIndexMapping[users[index]._id] = index; // store (_id, index) pair in IDIndexMapping

// I'm avoiding using `map` and using vanilla `for` loop for space efficiency
// as map returns a new array but with `for` loop, we can perform changes in-place

for(let outerIndex in spaces){ // Iterate through `spaces` array using index
    let challengers = spaces[outerIndex].challengers; // Get challengers array
    for(let innerIndex in challengers){ // Iterate through challengers array using index
        let ID = challengers[innerIndex]; // Get ID
        if(ID in IDIndexMapping) // If ID exists in IDIndexMapping
            spaces[outerIndex].challengers[innerIndex] = users[IDIndexMapping[ID]]; // Change ID to actual User object
    }
}
console.log(spaces)

输出

[ { _id: '5e1c4689429a8a0decf16f69',
    challengers: [ [Object], [Object], [Object] ] },
  { _id: '5e1c4eb9c9461510407d5e81',
    challengers: [ [Object], [Object] ] } ]

推荐阅读