TypeScript中从对象数组提取唯一区域及对应唯一国家列表
数组去重并按区域分组
现有包含重复region和regCountry字段的对象数组:
let arrOfObj = [ { "regCountry": "Germany", "region": "Europe" }, { "regCountry": "Germany", "region": "Europe" }, { "regCountry": "Spain", "region": "Europe" }, { "regCountry": "Spain", "region": "Europe" }, { "regCountry": "Italy", "region": "Europe" }, { "regCountry": "Austria", "region": "Europe" }, { "regCountry": "India", "region": "Asia" }, { "regCountry": "India", "region": "Asia" }, { "regCountry": "China", "region": "Asia" }, { "regCountry": "Japan", "region": "Asia" }, { "regCountry": "Congo", "region": "Africa" }, { "regCountry": "Egypt", "region": "Africa" }, { "regCountry": "Egypt", "region": "Africa" }, ]
需要转换为以下结构:每个唯一区域对应一组唯一国家列表
[ { region: "Europe", countries: ["Germany", "Spain", "Italy", "Austria"] }, { region: "Asia", countries: ["India", "China", "Japan"] }, { region: "Africa", countries: ["Congo","Egypt"] } ]
尝试使用.map()和.filter()未得到正确结果,求解决方案。
解决方案
可以使用Array.prototype.reduce()来实现分组和去重,这比单独用map和filter更高效,只需遍历数组一次:
const result = Object.values(arrOfObj.reduce((acc, { region, regCountry }) => { // 初始化当前区域的分组对象 if (!acc[region]) { acc[region] = { region, countries: [] }; } // 仅添加未存在的国家 if (!acc[region].countries.includes(regCountry)) { acc[region].countries.push(regCountry); } return acc; }, {})); console.log(result);
代码说明:
- reduce遍历累积:用对象作为累加器,以区域名作为键,存储对应区域的分组数据
- 区域初始化:如果累加器中没有当前区域,就创建包含区域名和空国家列表的对象
- 国家去重:检查当前国家是否已在对应区域的列表中,未存在则添加
- 转换为目标数组:用
Object.values()提取累加器中的所有分组对象,得到最终结构
如果处理大数据量,可改用Set提升去重效率:
const result = Object.values(arrOfObj.reduce((acc, { region, regCountry }) => { if (!acc[region]) { acc[region] = { region, countries: new Set() }; } acc[region].countries.add(regCountry); return acc; }, {})).map(item => ({ ...item, countries: Array.from(item.countries) })); console.log(result);
这个版本利用Set自动去重的特性,最后再将Set转换为数组,适合数据量较大的场景。
内容的提问来源于stack exchange,提问作者Vikramsinh Gaikwad
相关产品推荐
相关产品推荐

