循环遍历两个对象数组,在Id

时间:2018-01-08 19:44:49

标签: javascript arrays foreach

我对javascript很新,并且一直在寻找一个与我想要做的相匹配的例子,但我找不到解决方案。我有两个像这样构造的对象数组:

*注意:subscriptionArray中永远不会有重复的subId。

subscriptionArray = [
  {
    "subId" : 100,
    "companyId" : 5,
    "companyName" : "CompanyA",
    "domain" : "companyA.com"
  },
  {
    "subId" : 200,
    "companyId" : 6,
    "companyName" : "CompanyB",
    "domain" : "companyB.com"
  },
  {
    "subId" : 300,
    "companyId" : 5,
    "companyName" : "CompanyA",
    "domain" : "companyA.com"
  },

]

userArray = [
  {
    "name" : "John",
    "companyId" : 5,
    "email" : "john@companyA.com"      
  },
  {
    "Name" : "Frank",
    "CompanyId" : 5,
    "Email" : "Frank@companyA.com"     
  },
  {
    "name" : "Bill",
    "companyId" : 6,
    "email" : "bill@companyB.com"

  }

 ]

我想要的结果数组如下。我的目标是,遍历每个订阅,然后遍历每个用户,返回每个拥有与订阅的companyId匹配的companyId的用户。因此,因为companyA有2个用户,所以subId 100和300被返回两次。

resultArray = [
 {
  "subId" : 100,
  "companyId" : 5,
  "companyName" : "CompanyA",
  "domain" : "companyA.com",
  "name" : "John",
  "email" : "john@companyA.com"
 },
 {
  "subId" : 100,
  "companyId" : 5,
  "companyName" : "CompanyA",
  "domain" : "companyA.com",
  "name" : "Frank",
  "email" : "frank@companyA.com"
 },
 {
  "subId" : 200,
  "companyId" : 6,
  "companyName" : "CompanyB",
  "domain" : "companyB.com",
  "name" : "Bill",
  "email" : "bill@companyB.com"
 },
 {
  "subId" : 300,
  "companyId" : 5,
  "companyName" : "CompanyA",
  "domain" : "companyA.com",
  "name" : "John",
  "email" : "john@companyA.com"
 },
 {
  "subId" : 300,
  "companyId" : 5,
  "companyName" : "CompanyA",
  "domain" : "companyA.com",
  "name" : "Frank",
  "email" : "frank@companyA.com"
 },

]

我正在尝试这样的事情。

var newArray = [];    

subscriptionArray.forEach(function(subscription) {
  companyIdA = subscription.companyId;

  userArray.forEach(function(user) {
    companyIdB = user.companyId;
    if(companyIdB === companyIdA) {

        //Below I am trying to add a key 'subId' to the user 
        //object before pushing it to newArray.

      user.subId = subscription.subId;
      newArray.push(user)
    }

  })
})

因此上面的代码返回了正确数量的结果,但显然只是返回用户对象信息而不是来自subscriptionArray的任何信息。在将对象推入newArray之前,我尝试为subId添加一个新的键/值,但这最终会为每个类似的公司重复相同的subId(我相信因为它循环遍历一个订阅,然后是整个userArray,然后去到下一个订阅,但subId没有被更改。)

我正在使用更大的数据集,大约40个订阅和6个公司,我只是想获得一个对象数组,其中每个对象都是一个用户,与公司相关联,与订阅相关联(这会使如果公司有多个用户,则subscriptionId重复)。

环境:Google Apps脚本。我试图不使用jQuery,我相信GAS不支持LoDash。所以如果有人在vanilla JS中有一个完美的解决方案!

2 个答案:

答案 0 :(得分:2)

可以循环订阅并根据匹配的公司ID使用Array#find()作为关联用户。使用Object.assign()可以合并对象

编辑:仅因为缺乏对新方法的支持而恢复为ES5方法

var companyUsers = {}// hashmap of users using companyId as keys

userArray.forEach(function(user){
  companyUsers[user.companyId] = user;
});

// map new array based on each subscription
var res = subscriptionArray.map(function(sub){
  var user = companyUsers[sub.companyId];  
  if(user){
    for(var key in user){
      sub[key] = user[key]
    }
  }
  return sub;
});

console.log(res)
<script>
var subscriptionArray = [
  {
    "subId" : 100,
    "companyId" : 5,
    "companyName" : "CompanyA",
    "domain" : "companyA.com"
  },
  {
    "subId" : 200,
    "companyId" : 6,
    "companyName" : "CompanyB",
    "domain" : "companyB.com"
  },
  {
    "subId" : 300,
    "companyId" : 5,
    "companyName" : "CompanyA",
    "domain" : "companyA.com"
  },

]

var userArray = [
  {
    "name" : "John",
    "companyId" : 5,
    "email" : "john@companyA.com"      
  },
  {
    "Name" : "Frank",
    "CompanyId" : 5,
    "Email" : "Frank@companyA.com"     
  },
  {
    "name" : "Bill",
    "companyId" : 6,
    "email" : "bill@companyB.com"

  }

 ]
</script>

答案 1 :(得分:0)

 const byId = new Map();

 for(const {companyId, ...user} of userArray){
  const users = byId.get(companyId)
  if(users){
    users.push(user);
  } else {
    byId.set(companyId, [user]);
  }
 }

 const result = [];

  for(const subscription of subscriptionArray)
    for(const user of byId.get(subscription.companyId))
       result.push({ ...user, ...subscription });

这使用了companyId哈希表,这可能会使其更具性能。