对于对象数组:
[
{id: 1, name: "test", tagId: 1},
{id: 2, name: "test", tagId: 15},
{id: 3, name: "test", tagId: 5},
]
需要将特定属性列表(tagId)缩减为唯一数组1,15,5,调用一些批处理方法,例如,对实体列表接口进行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 join,以获得以下结果(如https://github.com/mtraynham/lodash-joins):
[
{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库可以做到这一点?它看起来像是微服务中非常常用的模式。
发布于 2018-06-01 02:55:08
我喜欢@RiverTam solution https://stackoverflow.com/a/50629965/962746。唯一要解决的问题是:源数组中的多个对象可以具有相同的tagId,因此我将索引响应对象而不是源对象:
const lodashUniq = require('lodash.uniq');
const lodashMap = require('lodash.map');
const source = [
{id: 1, name: "test", tagId: 1},
{id: 2, name: "test", tagId: 15},
{id: 3, name: "test", tagId: 5},
];
const uniqueIds = lodashUniq(lodashMap(source, 'tagId'));
const tags = await axios.get('http://apihost/tag', { id: uniqueIds });
const tagsIndex = new Map(tags.map(tag => [tag.id, tag]));
const result = source.map(s => (
{... s, tag: tagsIndex.get(s.tagId)}
));
发布于 2018-06-01 01:43:06
函数式方法。
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) }
));
发布于 2018-06-01 01:39:21
Interesting.Here是我的尝试。
const inits = [
{id: 1, name: "test", tagId: 1},
{id: 2, name: "test", tagId: 15},
{id: 3, name: "test", tagId: 5},
];
// Get all ids
const ids = inits.map(init => init.tagId);
const results = [
{id: 1, name: "tag1"},
{id: 15, name: "tag2"},
{id: 5, name: "tag3"},
];
// Add results to object
const final = inits.map(init => {
init.tag = results.find(res => res.id === init.tagId);
return init;
});
已更新
如果你可以确定对象的顺序保持不变,你可以加快速度:
// Add results to object
const final = inits.map((init, index) => {
init.tag = results.[index];
return init;
});
为什么JavaScript如此性感:(
https://stackoverflow.com/questions/50629814
复制相似问题