typescript 如何有效地迭代类型脚本中的2个大型对象数组

xt0899hw  于 2023-05-19  发布在  TypeScript
关注(0)|答案(2)|浏览(109)

我有2个样本数组如下

var marks=[{"id":1,"marks":null,"grade":"A"},{"id":1,"marks":90,"grade":null},{"id":1,"marks":90,"grade":"A"},{"id": 2, "marks": 65, "grade":"B"}]
var student=[{"id":1,"name":"john"},{"id": 2, "name": "anna"}]

在实时中,学生阵列的长度接近1000,标记阵列的长度接近10000。我必须遍历它们并检查id是否相同,然后在student数组中添加第一个非空标记和等级字段。我们不能在id上分组并合并2个数组,因为我们需要消除空值。我采用了使用循环的标准方法,但复杂度是n*m的数量级。如何优化?结果如下

var student=[{"id":1,"name":"john","marks":90,"grade":"A"},{"id": 2, "name": "anna", "marks": 65, "grade":"B"}]
insrf1ej

insrf1ej1#

students转换为Map(O(n)),并将其用作reduce的累加器:

new Map(student.map(o => [o.id, { ...o }]))

时间复杂度为O(m)。从累加器(m)中获取student,如果grademarks不是null,则使用Nullish coalescing assignment ( ??= )将它们分配给student,以避免更新现有属性:

if(grade !== null) student.grade ??= grade;
if(marks !== null) student.marks ??= marks;

复杂度为O(n)+ O(m)=> O(n + m)。

示例(TSPlayground):

const marks=[{"id":1,"marks":null,"grade":"A"},{"id":1,"marks":90,"grade":null},{"id":1,"marks":90,"grade":"A"},{"id": 2, "marks": 65, "grade":"B"}]
const students =[{"id":1,"name":"john"},{"id": 2, "name": "anna"}]

const result = Array.from(marks.reduce((m, { id, marks, grade }) => {
    const student = m.get(id)

    if(!student) return m

    if(grade !== null) student.grade ??= grade;
    if(marks !== null) student.marks ??= marks;

    return m
  }, new Map(students.map(o => [o.id, { ...o }])))
  .values()
)

console.log(result)
blpfk2vs

blpfk2vs2#

要查找marks和student数组之间的匹配项,可以使用嵌套循环来比较两个数组中每个对象的id属性。但是,为了优化循环以提高效率,您可以使用哈希表将每个student对象的id属性存储为键,并将student数组中的对象索引存储为值。然后,您可以循环遍历marks数组,对于每个对象,使用哈希表检查是否有对应的student对象。时间复杂度为O(n^2),时间复杂度为O(n)。

var marks=[{"id":1,"marks":null,"grade":"A"},{"id":1,"marks":90,"grade":null},{"id":1,"marks":90,"grade":"A"},{"id": 2, "marks": 65, "grade":"B"}]
var students=[{"id":1,"name":"john"},{"id": 2, "name": "anna"}]

// Create a map of student IDs
const studentMap = new Map(students.map((student) => [student.id, student]));

// Loop through marks and find matching students
marks.filter(mark => mark.marks && mark.grade)
     .map(mark => {
       const student = studentMap.get(mark.id);
       if (student) {
         // Execute your code here
         console.log(`${student.name} scored ${mark.marks} and got a grade of ${mark.grade}`);
     }
});

相关问题