如何通过匹配规则将字符串数组分组为目标结构的对象?
如何将字符串数组按前缀分组为对象?
首先,咱们先看看你现有代码里的几个小问题,这也是它没达到预期效果的原因:
indexOf('sender')的判断逻辑反了:当字符串包含sender时,indexOf返回0,而0在if条件里会被视为false,反而找不到的时候返回-1会被当成true,这完全搞反了判断逻辑。- 第二个
if里错误地把receiver开头的元素也推到了group1里,应该推到group2。 - 用
for...in遍历数组其实不太合适,它会遍历数组的索引(还有可能遍历到原型链上的属性),用for...of直接遍历元素更直观。
修复你的原始代码
先给你一个修复后的版本,能实现你要的效果:
var groups = { 'group1': [], 'group2': [] }; var mandate = ["sender.state","sender.city", "sender.postalcode", "receiver.state", "receiver.city", "receiver.postalcode"]; for (let item of mandate) { if (item.startsWith('sender')) { // 用startsWith比indexOf更直观,明确判断前缀 groups.group1.push(item); } else if (item.startsWith('receiver')) { groups.group2.push(item); } } console.log(groups);
更简便、灵活的方法:用Array.reduce
如果想让代码更简洁,同时扩展性更强(比如以后新增其他前缀分组),推荐用数组的reduce方法,它天生适合处理「数组转对象/分组」这类需求:
var mandate = ["sender.state","sender.city", "sender.postalcode", "receiver.state", "receiver.city", "receiver.postalcode"]; const groups = mandate.reduce((result, currentItem) => { // 提取每个元素的前缀(用.分割取第一个部分) const prefix = currentItem.split('.')[0]; // 把前缀映射到对应的组名 const groupName = prefix === 'sender' ? 'group1' : 'group2'; // 如果当前组还没初始化,先创建空数组 if (!result[groupName]) { result[groupName] = []; } // 将元素加入对应组 result[groupName].push(currentItem); return result; }, {}); // 初始值为空对象 console.log(groups);
如果以后需要新增更多分组(比如增加carrier前缀对应group3),只需要加一个映射关系就行,扩展性拉满:
// 前缀和组名的映射表,新增分组直接加在这里 const prefixMap = { sender: 'group1', receiver: 'group2', carrier: 'group3' }; const groups = mandate.reduce((result, currentItem) => { const prefix = currentItem.split('.')[0]; const groupName = prefixMap[prefix]; // 只处理在映射表里的前缀,避免无效元素干扰 if (groupName) { if (!result[groupName]) result[groupName] = []; result[groupName].push(currentItem); } return result; }, {});
这个方法不需要提前手动创建groups对象,代码更简洁,也更适配未来可能的需求变化。
内容的提问来源于stack exchange,提问作者3gwebtrain
相关产品推荐
相关产品推荐

