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

如何正确匹配users与contactInfo数组:解决姓名匹配错误问题

问题场景

当users数组中存在多个姓氏(last_name)相同的用户对象,而contactInfo数组中对应姓氏的联系人对象数量不同时,现有代码会出现匹配错误。例如users里有两个姓氏为Howell的用户,但contactInfo中只有一个Ervin Howell的联系人,现有代码会错误地将该联系人信息关联给Patricia Howell。

需求目标

将users数组与contactInfo数组进行匹配,需遵循以下规则:

  • 当用户姓氏在users数组中无重复时,按姓氏(last_name)匹配联系人;
  • 当用户姓氏在users数组中存在重复时,改为按名字(first_name)+姓氏组合匹配,确保唯一关联。
现有实现代码
let users = [
  {
    "id": 1,
    "first_name": "Leanne",
    "last_name": "Graham",
    "username": "Leanne.Graham"
  },
  {
    "id": 2,
    "first_name": "Ervin",
    "last_name": "Howell",
    "username": "Ervin.Howell"
  },
  {
    "id": 3,
    "first_name": "Clementine",
    "last_name": "Bauch",
    "username": "Clementine.Bauch"
  },
  {
    "id": 4,
    "first_name": "Patricia",
    "last_name": "Howell",
    "username": "Patricia.Howell"
  },
  {
    "id": 5,
    "first_name": "Patricia",
    "last_name": "Lebsack",
    "username": "Patricia.Lebsack"
  },
  {
    "id": 6,
    "first_name": "Chelsey",
    "last_name": "Dietrich",
    "username": "Chelsey.Dietrich"
  },
  {
    "id": 7,
    "first_name": "Dennis",
    "last_name": "Schulist",
    "username": "Dennis.Schulist"
  },
  {
    "id": 8,
    "first_name": "Kurtis",
    "last_name": "Weissnat",
    "username": "Kurtis.Weissnat"
  },
  {
    "id": 9,
    "first_name": "Nicholas",
    "last_name": "Runolfsdottir",
    "username": "Nicholas.Runolfsdottir"
  },
  {
    "id": 10,
    "first_name": "Glenna",
    "last_name": "Reichert",
    "username": "Glenna.Reichert"
  },
  {
    "id": 11,
    "first_name": "Clementina",
    "last_name": "DuBuque",
    "username": "Clementina.DuBuque"
  },
  {
    "id": 12,
    "first_name": "Dani",
    "last_name": "Reichert",
    "username": "Dani.Reichert"
  },
];

let contactInfo = [
  {
    "first_name": "Leanne",
    "last_name": "Graham",
    "email": "Leanne@Graham.biz",
    "phone": "1-770-736-8031 x56442",
    "website": "LeanneGraham.org"
  },
  {
    "first_name": "Ervin",
    "last_name": "Howell",
    "email": "Ervin@Howell.tv",
    "phone": "010-692-6593 x09125",
    "website": "ErvinHowell.net"
  },
  {
    "first_name": "Clementine",
    "last_name": "Bauch",
    "email": "Clementine@Bauch.net",
    "phone": "1-463-123-4447",
    "website": "ClementineBauch.info"
  },
  {
    "first_name": "Patricia",
    "last_name": "Lebsack",
    "email": "Patricia@Lebsack.org",
    "phone": "493-170-9623 x156",
    "website": "PatriciaLebsack.biz"
  },
  {
    "first_name": "Chelsey",
    "last_name": "Dietrich",
    "email": "Chelsey@Dietrich.ca",
    "phone": "(254)954-1289",
    "website": "ChelseyDietrich.info"
  },
  {
    "first_name": "Dennis",
    "last_name": "Schulist",
    "email": "Dennis@Schulist.info",
    "phone": "1-477-935-8478 x6430",
    "website": "DennisSchulist.org"
  },
  {
    "first_name": "Kurtis",
    "last_name": "Weissnat",
    "email": "Kurtis@Weissnat.biz",
    "phone": "210.067.6132",
    "website": "KurtisWeissnat.io"
  },
  {
    "first_name": "Nicholas",
    "last_name": "Runolfsdottir",
    "email": "Nicholas@Runolfsdottir.me",
    "phone": "586.493.6943 x140",
    "website": "NicholasRunolfsdottir.com"
  },
  {
    "first_name": "Glenna",
    "last_name": "Reichert",
    "email": "Glenna@Reichert.io",
    "phone": "(775)976-6794 x41206",
    "website": "GlennaReichert.com"
  },
  {
    "first_name": "Dani",
    "last_name": "Reichert",
    "email": "Dani@Reichert.io",
    "phone": "(775)976-6794 x41206",
    "website": "DaniReichert.com"
  },
  {
    "first_name": "Clementina",
    "last_name": "DuBuque",
    "email": "Clementina@DuBuque.biz",
    "phone": "024-648-3804",
    "website": "ClementinaDuBuque.net"
  }
];

let usersArray = [];

for(let el of users) {
    let obj1 = [];
    
    for(let val of contactInfo) {
        if(el.last_name == val.last_name) {
            obj1.push(val);
        }    
    }
    
    if(obj1.length > 1) {
        let contactDup = obj1;
        for(let val of contactDup) {
            if(el.first_name == val.first_name) {
                let contact = val;
                let obj = Object.assign(el, contact);
                usersArray.push(obj);
            }
        }
    } else {
        let contact = obj1[0];
        let obj = Object.assign(el, contact);
        usersArray.push(obj);
    }
}

console.log('usersArray', usersArray);
问题排查

现有代码的核心错误在于判断逻辑的依据错误:

  • 原代码通过contactInfo中当前用户姓氏对应的联系人数量来决定匹配方式,而不是根据users数组中当前用户姓氏的重复数量;
  • 例如users中有2个Howell用户,但contactInfo中只有1个Howell联系人,原代码会进入else分支直接按姓氏匹配,导致Patricia Howell错误关联Ervin Howell的联系人信息;
  • 此外,Object.assign(el, contact)会直接修改原users数组中的对象,造成原数据污染。
修正后的代码
let users = [
  { "id": 1, "first_name": "Leanne", "last_name": "Graham", "username": "Leanne.Graham" },
  { "id": 2, "first_name": "Ervin", "last_name": "Howell", "username": "Ervin.Howell" },
  { "id": 3, "first_name": "Clementine", "last_name": "Bauch", "username": "Clementine.Bauch" },
  { "id": 4, "first_name": "Patricia", "last_name": "Howell", "username": "Patricia.Howell" },
  { "id": 5, "first_name": "Patricia", "last_name": "Lebsack", "username": "Patricia.Lebsack" },
  { "id": 6, "first_name": "Chelsey", "last_name": "Dietrich", "username": "Chelsey.Dietrich" },
  { "id": 7, "first_name": "Dennis", "last_name": "Schulist", "username": "Dennis.Schulist" },
  { "id": 8, "first_name": "Kurtis", "last_name": "Weissnat", "username": "Kurtis.Weissnat" },
  { "id": 9, "first_name": "Nicholas", "last_name": "Runolfsdottir", "username": "Nicholas.Runolfsdottir" },
  { "id": 10, "first_name": "Glenna", "last_name": "Reichert", "username": "Glenna.Reichert" },
  { "id": 11, "first_name": "Clementina", "last_name": "DuBuque", "username": "Clementina.DuBuque" },
  { "id": 12, "first_name": "Dani", "last_name": "Reichert", "username": "Dani.Reichert" },
];

let contactInfo = [
  { "first_name": "Leanne", "last_name": "Graham", "email": "Leanne@Graham.biz", "phone": "1-770-736-8031 x56442", "website": "LeanneGraham.org" },
  { "first_name": "Ervin", "last_name": "Howell", "email": "Ervin@Howell.tv", "phone": "010-692-6593 x09125", "website": "ErvinHowell.net" },
  { "first_name": "Clementine", "last_name": "Bauch", "email": "Clementine@Bauch.net", "phone": "1-463-123-4447", "website": "ClementineBauch.info" },
  { "first_name": "Patricia", "last_name": "Lebsack", "email": "Patricia@Lebsack.org", "phone": "493-170-9623 x156", "website": "PatriciaLebsack.biz" },
  { "first_name": "Chelsey", "last_name": "Dietrich", "email": "Chelsey@Dietrich.ca", "phone": "(254)954-1289", "website": "ChelseyDietrich.info" },
  { "first_name": "Dennis", "last_name": "Schulist", "email": "Dennis@Schulist.info", "phone": "1-477-935-8478 x6430", "website": "DennisSchulist.org" },
  { "first_name": "Kurtis", "last_name": "Weissnat", "email": "Kurtis@Weissnat.biz", "phone": "210.067.6132", "website": "KurtisWeissnat.io" },
  { "first_name": "Nicholas", "last_name": "Runolfsdottir", "email": "Nicholas@Runolfsdottir.me", "phone": "586.493.6943 x140", "website": "NicholasRunolfsdottir.com" },
  { "first_name": "Glenna", "last_name": "Reichert", "email": "Glenna@Reichert.io", "phone": "(775)976-6794 x41206", "website": "GlennaReichert.com" },
  { "first_name": "Dani", "last_name": "Reichert", "email": "Dani@Reichert.io", "phone": "(775)976-6794 x41206", "website": "DaniReichert.com" },
  { "first_name": "Clementina", "last_name": "DuBuque", "email": "Clementina@DuBuque.biz", "phone": "024-648-3804", "website": "ClementinaDuBuque.net" }
];

// 统计users数组中每个姓氏的出现次数
const lastNameCount = users.reduce((countMap, user) => {
  countMap[user.last_name] = (countMap[user.last_name] || 0) + 1;
  return countMap;
}, {});

// 创建contactInfo的索引表,优化匹配效率
const contactIndex = contactInfo.reduce((indexMap, contact) => {
  // 用全名作为键,确保唯一匹配
  const fullName = `${contact.first_name}_${contact.last_name}`;
  indexMap[fullName] = contact;
  // 保留姓氏索引,用于无重复姓氏的匹配
  if (!indexMap[contact.last_name]) {
    indexMap[contact.last_name] = contact;
  }
  return indexMap;
}, {});

const usersArray = users.map(user => {
  let matchedContact;
  const hasDuplicateLastName = lastNameCount[user.last_name] > 1;
  
  if (hasDuplicateLastName) {
    // 姓氏重复时,按全名匹配
    const fullName = `${user.first_name}_${user.last_name}`;
    matchedContact = contactIndex[fullName];
  } else {
    // 姓氏无重复时,按姓氏匹配
    matchedContact = contactIndex[user.last_name];
  }
  
  // 返回新对象,避免修改原users数组
  return matchedContact ? {...user, ...matchedContact} : {...user};
});

console.log('usersArray', usersArray);
修正逻辑说明
  1. 统计姓氏重复次数:通过reduce遍历users数组,生成每个姓氏的出现次数映射表,以此判断是否需要切换匹配规则;
  2. 创建联系人索引:提前将contactInfo转换为索引表,用全名(first_name+last_name)和姓氏作为键,大幅提升匹配效率;
  3. 匹配逻辑修正:
    • 若当前用户姓氏在users中重复,使用全名精确匹配联系人;
    • 若姓氏无重复,直接用姓氏匹配联系人;
  4. 避免原数据污染:使用展开运算符{...user, ...matchedContact}创建新对象,不修改原users数组中的数据。

内容的提问来源于stack exchange,提问作者Abdur Raziq Khan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 13:57:20