将一个数组中的值分配给嵌套数组的最有效方法

时间:2018-10-21 19:42:20

标签: javascript arrays

给出一个包含子集合的集合(以下代码段中的users),以及另一个包含我需要合并的属性的集合(organizations),这些集合需要合并到users的子集合中,最有效的方法是什么?

下面的代码可以工作,但是嵌套迭代对我来说从来没有那么好过。此外,生产环境具有成百上千的结果,因此性能至少是一个考虑因素。

仅供参考,我正在利用lodash库,并且知道使用该库 not 会带来一些性能提升-但是,我希望有人可以提供更多的性能解决问题的有效方法。

下面的代码查找组织的名称,然后将该名称添加到users数组中以供应用程序的其他部分使用。

(数据结构来自API,无法更改。)

// organizations are actually fetched from an API via Observable.  Can change at any time.
const organizations = [{
    organization_id: 5,
    organization_name: 'Sample 1'
  },
  {
    organization_id: 6,
    organization_name: 'Sample 2'
  },
  {
    organization_id: 9,
    organization_name: 'Sample 3'
  },
  // etc...
];

// users are actually fetched from an API via Observable.  Can change at any time.
const users = [{
    user_name: 'User 1',
    organizations: [{
        organization_id: 9,
        organization_role: 'Limited'
      },
      {
        organization_id: 6,
        organization_role: 'Admin'
      }
    ]
  },
  {
    user_name: 'User 2',
    organizations: [{
        organization_id: 5,
        organization_role: 'Limited'
      },
      {
        organization_id: 6,
        organization_role: 'Limited'
      }
    ]
  },
  // etc...
];


document.addEventListener('DOMContentLoaded', () => {
  _.forEach(users, (user) => {
    _.forEach(user.organizations, (organization) => {
      organization.organization_name = _.get(_.find(organizations, ['organization_id', organization.organization_id]), 'organization_name', '?');
    });
  });
  console.log(users);
}, false);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

1 个答案:

答案 0 :(得分:1)

由于_.find()是一个O(n)操作(其中n是组织const的长度),而forEach操作是O(m * l)(m个用户,l个平均每个组织的数目用户),则总操作为O(n * m * l)。您可以通过首先映射组织将其降低为O(n + m * l),这是一个O(n)操作(例如,使用_.keyBy())。

// organizations are actually fetched from an API via Observable.  Can change at any time.
const organizations = [{"organization_id":5,"organization_name":"Sample 1"},{"organization_id":6,"organization_name":"Sample 2"},{"organization_id":9,"organization_name":"Sample 3"}];

// users are actually fetched from an API via Observable.  Can change at any time.
const users = [{"user_name":"User 1","organizations":[{"organization_id":9,"organization_role":"Limited"},{"organization_id":6,"organization_role":"Admin"}]},{"user_name":"User 2","organizations":[{"organization_id":5,"organization_role":"Limited"},{"organization_id":6,"organization_role":"Limited"}]}];


document.addEventListener('DOMContentLoaded', () => {
  const orgDict = _.keyBy(organizations, 'organization_id');
  _.forEach(users, (user) => {
    _.forEach(user.organizations, (organization) => {
      organization.organization_name = _.get(orgDict['organization_id'], 'organization_name', '?');
    });
  });
  console.log(users);
}, false);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>