首页 > 解决方案 > 用于收集对象属性、进行批处理并将结果映射回对象的 Javascript 库

问题描述

对于对象数组:

[
    {id: 1, name: "test", tagId: 1},
    {id: 2, name: "test", tagId: 15},
    {id: 3, name: "test", tagId: 5},
]

需要将特定属性列表(tagId)缩减为唯一数组[1,15,5],调用一些批处理方法,例如,对实体列表的API进行http请求:

async (ids) => await axios.get('http://apihost/tag', {id: ids})

对于对象的结果数组:

[
    {id: 1, name: "tag1"},
    {id: 15, name: "tag2"},
    {id: 5, name: "tag3"},
]

最后需要通过 ID 属性将此对象映射到由 result.id => original.tagId 匹配的原始对象数组,实际上是对两个数组进行 SQL 连接来得到这个(如https://github.com/mtraynham/lodash -加入):

[
    {id: 1, name: "test", tagId: 1, tag: {id: 1, name: "tag1"}},
    {id: 2, name: "test", tagId: 15, tag: {id: 15, name: "tag2"}},
    {id: 3, name: "test", tagId: 5, tag: {id: 5, name: "tag3"}},
]

我已经为此使用 API 编写了一个 PHP 库,例如:

new BulkMap(source).map(
  'tagId',
  'tag',
  async (ids) => axios.get('http://apihost/tag', {id: ids})
);

但现在我在 JS 中需要这个。是否有任何 Javascript/NodeJS 库可以这样做?它看起来像是微服务中非常常用的模式。

标签: javascriptnode.jsmicroservices

解决方案


一种功能性方法。

const { map, uniq } = require('lodash/fp');

const arr = /* you say you already have this */;

const uniqueIds = uniq(map('tagId', arr));
const objects = await axios.get('http://apihost/tag', { id: uniqueIds });
const associated = arr.map(({ id, tagId, name }) => (
  { id, tagId, name, tag: objects.find(o => o.id === tagId) };
));

如果你想索引(这可能会避免 O(N^2) 解决方案)

const byTagId = new Map();
arr.forEach(o => byTagId.set(o.tagId, o));
const objects = await axios.get('http://apihost/tag', { id: byTagId.keys() });
const associated = arr.map(({ id, tagId, name }) => (
  { id, tagId, name, tag: byTagId.get(tagId) }
));

推荐阅读