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

如何优化对象数组与多数组的属性比对逻辑,返回匹配/不匹配数组

优化学生数据匹配与存储性能方案

需求背景

现有学生对象数组如下:

[
  {
    studentName: 'Vishesh Kumar',
    dateOfBirth: '14-03-2023',
    parentName: 'Lalu Kumar',
    examName: 'UPSC CDS',
    dateOfExam: '14-03-1998',
    centerName: 'St Annas High School',
    centerCode: 'RN1001',
    studentEmail: 'Visheshkumar@Gmail.in',
    studentPhoneNumber: 999043139,
    address: 'D-31,Sectory-73,Noida Up India',
    city: 'Noida',
    state: 'UTTAR PRADESH',
    zipcode: 201301
  },
  {
    studentEnrollmentID: 'EN1000006',
    studentName: 'Arnav Singh',
    dateOfBirth: '14-03-2023',
    parentName: 'Arun Singh',
    examName: 'UPSC CDS',
    dateOfExam: '14-03-1998',
    centerName: 'St Annas High School',
    centerCode: 'RN1001',
    studentEmail: 'ArnavSingh@Gmail.in',
    studentPhoneNumber: 6990433540,
    address: 'D-31,Sectory-44,Noida Up India',
    city: 'Noida',
    state: 'UTTAR PRADESH',
    zipcode: 201301
  },
  {
    studentEnrollmentID: 'EN1000004',
    studentName: 'Sanjay Singh',
    dateOfBirth: '14-03-2023',
    parentName: 'Mohan Singh',
    examName: 'UPSC CDS',
    dateOfExam: '14-03-1998',
    centerName: 'St Peters High School',
    centerCode: 'RN1003',
    studentEmail: 'SanjaySingh@Gmail.in',
    StudentPhoneNumber: 9990433538,
    address: 'D-31,Sectory-53,Noida Up India',
    city: 'Noida',
    state: 'UTTAR PRADESH',
    zipcode: 201301
  }
]

需要将每个学生对象的centerName与以下数组比对,centerCode与另一数组比对:

const centerNames = ['St Annas High School', 'KV Music School']
const centerCodes = ['RN1001','RN1002']

最终要返回两个新数组:

  • 第一个数组:包含同时满足centerName在centerNames中且centerCode在centerCodes中的学生对象
  • 第二个数组:包含未匹配其中一个或两个条件的学生对象

现有问题

当前采用嵌套for循环+if-else的实现方式,且串行处理异步存储操作,在数组规模增大时性能极差:

for (student of students) {
  if (student.examCode == examCode) {
    const newStudent = await new Student(student);
    await newStudent.save().then(async (result: any) => {
      studentsUploaded.push(result);
    }).catch(async (error: any) => {
      studentsRejected.push(newStudent);
      errors.push(error);
    });
  } else {
    studentsRejected.push(student);
    errors.push(`${examCode} does not match`);
  }
}

优化方案

1. 用Set优化匹配查找性能

数组的includes方法是O(n)时间复杂度,转成Set后查找是O(1),大规模数据下效率提升明显:

const validCenterNames = new Set(centerNames);
const validCenterCodes = new Set(centerCodes);

2. 单次遍历完成分类

用数组的reduce方法一次遍历完成学生的分类,避免多次循环:

const [matchedStudents, unmatchedStudents] = students.reduce((acc, student) => {
  const isMatched = validCenterNames.has(student.centerName) && validCenterCodes.has(student.centerCode);
  if (isMatched) {
    acc[0].push(student);
  } else {
    acc[1].push(student);
  }
  return acc;
}, [[], []] as [typeof students, typeof students]);

3. 并行处理异步存储操作

原来的串行await会逐个等待存储完成,改用Promise.all并行处理,大幅提升存储效率:

const errors: any[] = [];
const studentsUploaded: any[] = [];
const studentsRejected: any[] = [...unmatchedStudents];

// 并行处理匹配学生的存储
const savePromises = matchedStudents.map(async (student) => {
  try {
    const newStudent = new Student(student);
    const result = await newStudent.save();
    studentsUploaded.push(result);
  } catch (error) {
    studentsRejected.push(student);
    errors.push(error);
  }
});

// 等待所有存储操作完成
await Promise.all(savePromises);

完整优化代码

async function processStudents(students: any[], examCode: string) {
  // 转Set优化查找
  const validCenterNames = new Set(['St Annas High School', 'KV Music School']);
  const validCenterCodes = new Set(['RN1001','RN1002']);

  const errors: any[] = [];
  // 一次遍历分类学生并记录不匹配原因
  const [matchedStudents, unmatchedStudents] = students.reduce((acc, student) => {
    // 同时匹配考点信息和考试编码
    const isEligible = validCenterNames.has(student.centerName) && 
                      validCenterCodes.has(student.centerCode) &&
                      student.examCode === examCode;
    if (isEligible) {
      acc[0].push(student);
    } else {
      acc[1].push(student);
      // 精准记录错误原因
      if (student.examCode !== examCode) {
        errors.push(`${examCode} does not match for student ${student.studentName}`);
      } else {
        errors.push(`Invalid center info for student ${student.studentName}`);
      }
    }
    return acc;
  }, [[], []] as [typeof students, typeof students]);

  const studentsUploaded: any[] = [];
  const studentsRejected: any[] = [...unmatchedStudents];

  // 并行存储匹配的学生
  const savePromises = matchedStudents.map(async (student) => {
    try {
      const newStudent = new Student(student);
      const result = await newStudent.save();
      studentsUploaded.push(result);
    } catch (error) {
      studentsRejected.push(student);
      errors.push(error);
    }
  });

  await Promise.all(savePromises);

  return { studentsUploaded, studentsRejected, errors };
}

优化点说明

  • 查找性能:Set的O(1)查找替代数组O(n)查找,数据量越大优势越明显
  • 遍历效率:一次遍历完成分类,减少循环次数
  • 异步性能:并行处理存储操作,避免串行等待,IO密集型场景下性能提升数倍

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 20:24:56