合并国家与城市数组后为Select组件按国家名排序且不破坏选项值的方法
解决方案
先修正你给出的city数组的语法笔误(Italy后缺失闭合双引号):
const country = [{id:1, name:"Mexico"}, {id:2, name: "Canada"}, {id:3, name:"Italy"}]; const city = [{id:19, name: "Ottava",country:{id:2, name:"Canada"}}, {id:23, name:"Roma",country:{id:3, name: "Italy"}}];
你只需要在合并数组后、渲染前,调用数组的sort方法自定义排序规则即可,原有渲染逻辑不需要做任何修改,不会破坏value赋值和显示规则。
完整实现代码
// 合并数组 var newArray = country.concat(city); // 自定义排序 newArray.sort((a, b) => { // 提取当前项对应的排序基准国家名 const getSortCountryName = (item) => item.country ? item.country.name : item.name; const nameA = getSortCountryName(a); const nameB = getSortCountryName(b); // 第一规则:按国家名称字母序排序 const countryOrder = nameA.localeCompare(nameB); if (countryOrder !== 0) return countryOrder; // 第二规则:同国家下,国家项排在城市项前 const aIsCountry = !a.country; const bIsCountry = !b.country; if (aIsCountry && !bIsCountry) return -1; if (!aIsCountry && bIsCountry) return 1; // 可选:同类型项按自身名称排序,无需求可直接返回0 return a.name.localeCompare(b.name); })
渲染部分保持你原有逻辑不变即可:
<Select> {newArray.map((i) => ( <Option value={i.country ? i.country.id : i.id}> {i.name} {i.country && ", " + i.country.name} </Option> ))} </Select>
排序说明
- 首先提取所有项关联的国家名称作为第一排序维度,用
localeCompare实现自然的字母序排序 - 同一国家的项,通过是否存在
country属性区分类型,国家项优先级高于城市项 - 完全兼容你原有渲染逻辑,不会修改任何项的属性值,符合你的要求。
内容的提问来源于stack exchange,提问作者Gucal
相关产品推荐
相关产品推荐

