JavaScript循环数组并以brow_id为键创建新对象的疑问
分析你的数组转对象实现
首先,你的代码基本逻辑是正确的——它确实能将原数组转换为一个以每个元素的brow_id属性为键、元素本身为值的对象。不过这里有个关键细节需要你注意:
当前代码的行为
先看你的原代码:
var array = [{"tom": "red", "part":"green", "brow_id":45}, {"tom": "red", "part":"yellow", "brow_id":1}, {"tom": "red", "part":"yellow", "brow_id":2}, {"tom": "maroon", "part":"cyan", "brow_id":45}]; var newarray = {}; array.forEach(function(elem) { newarray[elem.brow_id] = elem; });
运行这段代码后,newarray的最终结构会是:
{ "1": {"tom": "red", "part":"yellow", "brow_id":1}, "2": {"tom": "red", "part":"yellow", "brow_id":2}, "45": {"tom": "maroon", "part":"cyan", "brow_id":45} }
你会发现,原数组中两个brow_id=45的元素,最后只有最后一个被保留了——因为forEach遍历到第二个brow_id=45的元素时,会直接覆盖掉之前赋值的newarray[45]。
两种场景的处理方案
如果你就是想保留每个
brow_id对应的最后一个元素
那你的代码完全没问题,不需要修改。这是一种常见的需求(比如用最新的数据覆盖旧数据)。如果你想收集所有相同
brow_id的元素(不覆盖)
这种情况下,你需要把每个键对应的值改成数组,用来存储所有匹配的元素。可以用Array.reduce()来实现:var array = [{"tom": "red", "part":"green", "brow_id":45}, {"tom": "red", "part":"yellow", "brow_id":1}, {"tom": "red", "part":"yellow", "brow_id":2}, {"tom": "maroon", "part":"cyan", "brow_id":45}]; var newObject = array.reduce((accumulator, currentElem) => { const browId = currentElem.brow_id; // 如果键不存在,先初始化一个空数组 if (!accumulator[browId]) { accumulator[browId] = []; } // 将当前元素加入对应数组 accumulator[browId].push(currentElem); return accumulator; }, {});运行后
newObject的结构会是:{ "1": [{"tom": "red", "part":"yellow", "brow_id":1}], "2": [{"tom": "red", "part":"yellow", "brow_id":2}], "45": [ {"tom": "red", "part":"green", "brow_id":45}, {"tom": "maroon", "part":"cyan", "brow_id":45} ] }
总结
你的原始代码在“保留每个brow_id最后一个元素”的需求下是完全正确的。如果你的需求是保留所有相同brow_id的元素,就可以改用上面的reduce实现。
内容的提问来源于stack exchange,提问作者John Doe
相关产品推荐
相关产品推荐

