You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中分组JSON数据时元素未全部加入键值对问题

问题:Angular中分组JSON数据时元素未全部加入目标对象

原始数据

var records= [ 
  { "category" : "chinese", "name": "noodles" }, 
  { "category" : "chinese", "name": "veg" }, 
  { "category" : "Indian", "name": "Dal" }, 
  { "category" : "Indian", "name": "Rajma" }, 
  { "category" : "chinese", "name": "chicken" }, 
  { "category" : "continental", "name": "fish" }, 
  { "category" : "continental", "name": "Veg" }, 
  { "category" : "Indian", "name": "Paratha" } 
]

预期分组结果

var newcat = { 
  "chinese": [ 
    { "name": "noodles", "category": "chinese" }, 
    {"name": "veg", "category": "chinese"}, 
    {"name":"chicken", "category": "chinese"} 
  ], 
  "indian": [ 
    { "name": "Dal", "category": "indian" }, 
    {"name": "rajma", "category": "indian"}, 
    {"name":"Paratha", "category": "indian" } 
  ], 
  "continental": [ 
    { "name": "fish", "category": "continental" }, 
    { "name": "Veg", "category": "continental"} 
  ] 
}

当前使用的代码

var newcat={} 
var arr= {} 
var isPresent= false; 
var cat 
for (let i=0;i< records.length;i++) { 
  cat= records[i].category 
  for(let item in newcat) { 
    if(cat == item) { 
      isPresent= true 
    } else { 
      isPresent= false 
    } 
  } 
  if(isPresent== false){ 
    newcat[cat]= [] 
  } else { 
    newcat[cat].push(records[i]) 
    console.log("===>",newcat) 
  } 
}

问题现象

  • 预期控制台输出:
    {chinese: Array(3), indian: Array(3), continental: Array(2)}
    
  • 实际控制台输出:
    {chinese: Array(0), indian: Array(1), continental: Array(1)}
    

问题分析

你的核心问题出在判断分类是否存在的逻辑上。当你遍历newcat的属性时,只要遇到一个和当前cat不匹配的属性,就会把isPresent设为false,这会覆盖之前可能已经设为true的结果。举个例子:
当newcat已经有chinese和indian两个属性时,处理下一个chinese分类的元素时,遍历到indian时会把isPresent改成false,导致你错误地认为chinese不存在,进而执行newcat[cat] = []清空之前的数组,后续的push自然也无法正确累积元素。

另外还有一个小细节:预期结果里分类名是小写的(比如indian),但原始数据里有大写的Indian,你可能需要统一大小写,避免出现重复分类。

解决方案

方案1:修复原有循环逻辑

调整判断分类是否存在的方式,不要在遍历中反复修改isPresent,而是直接检查newcat是否包含当前分类:

var newcat = {};
for (let i = 0; i < records.length; i++) {
  // 统一分类名为小写,避免大小写导致的重复
  const cat = records[i].category.toLowerCase();
  // 直接检查当前分类是否在newcat中,无需遍历所有属性
  if (!newcat[cat]) {
    newcat[cat] = [];
  }
  // 复制对象并统一category大小写,和预期结果保持一致
  const item = {...records[i], category: cat};
  newcat[cat].push(item);
}
console.log(newcat);

方案2:使用数组reduce方法(更简洁推荐)

在JavaScript/Angular中,用reduce方法可以更优雅地完成分组逻辑,代码更简洁也不易出错:

const newcat = records.reduce((acc, item) => {
  const cat = item.category.toLowerCase();
  // 如果分类不存在,初始化空数组;否则直接push元素
  acc[cat] = acc[cat] || [];
  // 复制并统一category大小写
  acc[cat].push({...item, category: cat});
  return acc;
}, {});
console.log(newcat);

这两种方案都能得到你预期的分组结果,其中reduce是更符合现代JavaScript风格的写法,推荐使用。


内容的提问来源于stack exchange,提问作者Udit Gogoi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:54:44