按 id 规范化对象数组和键
Posted
技术标签:
【中文标题】按 id 规范化对象数组和键【英文标题】:Normalise array of objects & key by id 【发布时间】:2017-06-15 21:32:00 【问题描述】:我希望规范化从 API 返回的一些数据。已经在项目中使用下划线。
var res = [
badge_no: 123,
id: 1,
name: 'bob'
,
badge_no: 456,
id: 2,
name: 'bill'
,
badge_no: 789,
id: 3,
name: 'ben'
,
// etc
];
我希望创建一个如下所示的数据结构:
var normalisedRes = [
1:
badge_no: 123,
id: 1,
name: 'bob'
,
2:
badge_no: 456,
id: 2,
name: 'bill'
,
3:
badge_no: 789,
id: 3,
name: 'ben'
];
将 id 保存在 obj 中很重要。我相信我可以通过 reduce
完成此任务,但我正在苦苦挣扎。
感谢您的帮助!
编辑:这个问题现在已经得到解答。
根据这里的一些建议,我决定对数据进行规范化以返回一个 obj,如下所示:
'1': data, '2':data, '3':data
为此,我使用了 reduce,正如我最初认为的那样:
var normalised = res.reduce((acc, person) =>
acc[person.id] = person;
return acc;
, );
再次感谢大家的回答!
【问题讨论】:
你能分享你到目前为止尝试过的代码吗? 所以你想要一个对象数组,每个对象都包含一个键(它的id
)?那是您开始时的“更好”或标准化版本吗?你为什么想要那个结构?
最终结构没有意义。为什么需要一个数组来包装一个对象?
您希望密钥是ID
s 还是indexes (+1)
?
请在您的问题中编辑您关于键是 ID 的最后评论。此外,避免在您的问题中编辑答案,而是接受其中一个答案,如有必要,请在最终决定中对其进行评论。如果没有一个答案符合您的需要,我们鼓励您提供自己的答案并接受它。
【参考方案1】:
_.indexBy
完全符合要求。
【讨论】:
【参考方案2】:这些解决方案不是与直觉相反吗,在数组上使用 HashTable 的重点是,如果必须使用 Array.find((item)=>...) 它必须遍历每条记录为了找到你想要的,reduce 会遍历数组中的每一项,map 会返回一个新数组,即:你会得到一个带有 objectKey:...object 的数组,最好的办法是是从您的后端返回一个哈希,这实际上是 firebase 所做的,例如
【讨论】:
【参考方案3】:您可以将Array#map
与对象一起使用,并使用id
设置键并返回该对象。
var array = [ badge_no: 123, id: 1, name: 'bob' , badge_no: 456, id: 2, name: 'bill' , badge_no: 789, id: 3, name: 'ben' ],
result = array.map(function (a)
var o = ;
o[a.id] = a;
return o;
);
console.log(result);
.as-console-wrapper max-height: 100% !important; top: 0;
使用 ES6,您可以使用计算属性。
var array = [ badge_no: 123, id: 1, name: 'bob' , badge_no: 456, id: 2, name: 'bill' , badge_no: 789, id: 3, name: 'ben' ],
result = array.map(a => ( [a.id]: a ));
console.log(result);
.as-console-wrapper max-height: 100% !important; top: 0;
【讨论】:
虽然是正确的答案,难道不应该等待OP分享努力吗? 我觉得链接不对……不是Map,是Array.prototype.map
【参考方案4】:
您可以通过Array#map()
做到这一点
var res = [badge_no:123, id:1, name:'bob',badge_no:456, id:2, name:'bill',badge_no:789, id:3, name:'ben'];
var result = res.map(e => ([e.id]: e))
console.log(result)
如果您愿意,也可以使用reduce()
,但map()
应该可以完成工作。
var res = [badge_no:123, id:1, name:'bob',badge_no:456, id:2, name:'bill',badge_no:789, id:3, name:'ben'];
var result = res.reduce((r, e) => (r.push([e.id]: e), r), [])
console.log(result)
【讨论】:
虽然是正确的答案,难道不应该等待OP分享努力吗?【参考方案5】:您不能使用整数作为对象的键。所以你的例子是不可能的。 请参阅此相关问题:javascript: Using integer as key in associative array?
【讨论】:
你可以使用任何类型的键,它会自动装箱成一个字符串 这通常是不好的做法,因为它会强制您访问对象内部的属性,例如console.log(normalisedRes["3"]) 而不是像 console.log(normalisedRes.3) 这样会产生错误。normalisedRes[3]
也可以工作,并且在将计算键的自动化过程中,您必须使用括号语法访问值
虽然这是不好的做法,但这正是 OP 想要的。这个答案对了一半。这个例子是可能的。以上是关于按 id 规范化对象数组和键的主要内容,如果未能解决你的问题,请参考以下文章