【问题标题】:Issue with comparing two arrays and merging based on the merged array with distinct objects比较两个数组并基于具有不同对象的合并数组进行合并的问题
【发布时间】:2020-08-11 02:57:06
【问题描述】:

最初数组 $scope.distinctCourseUsers 将为空,在每个动态新响应之后,我会将所有对象附加到前一个列表中,包括新的对象集 然后使用reduce方法消除数组的重复并存储回$scope.distinctCourseUsers

$scope.courseUsers = response;
Array.prototype.push.apply($scope.distinctCourseUsers,response); 
distinctCourseUsers = result = $scope.distinctCourseUsers.reduce((unique, o) => {
    if(!unique.some(obj => obj.Id === o.Id )) {
    unique.push(o);
    }
    return unique;
},[]);

$scope.courseUsers = response;

对于 I 响应,两个新的数组对象将被存储到 $scope.courseUsers

console.log($scope.courseUsers);

(2) [{…}, {…}]
0: {Id: 22410, Name: "test01", RoleType: "XL Teacher", IsEnrolled: false, EnrolledOn: "", …}
1: {Id: 22411, Name: "test02", RoleType: "XL Teacher", IsEnrolled: false, EnrolledOn: "", …}

将空的$scope.distinctCourseUsers 数组与存储在$scope.courseUsers 中的响应合并

Array.prototype.push.apply($scope.distinctCourseUsers,response); 
console.log($scope.distinctCourseUsers);

对于 II 响应将有两个新对象,因此将先前的 Array List(2) + (New Array List(2) + Previous Array List(4)) Totally (2+2+4=6) 附加到$scope.distinctCourseUsers数组列表

(4) [{…}, {…}, {…}, {…}]
0: {Id: 22410, Name: "test01", RoleType: "XL Teacher", IsEnrolled: false, EnrolledOn: "", …}
1: {Id: 22411, Name: "test02", RoleType: "XL Teacher", IsEnrolled: false, EnrolledOn: "", …}
2: {Id: 22410, Name: "test01", RoleType: "XL Teacher", IsEnrolled: false, EnrolledOn: "", …}
3: {Id: 22411, Name: "test02", RoleType: "XL Teacher", IsEnrolled: false, EnrolledOn: "", …}
4: {Id: 22412, Name: "test03", RoleType: "XL Teacher", IsEnrolled: false, EnrolledOn: "", …}
5: {Id: 22413, Name: "test04", RoleType: "End user", IsEnrolled: false, EnrolledOn: "", …}

// The below reduce opertator will eliminate all the redundant objects
distinctCourseUsers = result = $scope.distinctCourseUsers.reduce((unique, o) => {
    if(!unique.some(obj => obj.Id === o.Id )) {
    unique.push(o);
    }
    return unique;
},[]);


console.log(distinctCourseUsers);

实际和预期结果:

0: {Id: 22410, Name: "test01", RoleType: "XL Teacher", IsEnrolled: false, EnrolledOn: "", …}
1: {Id: 22411, Name: "test02", RoleType: "XL Teacher", IsEnrolled: false, EnrolledOn: "", …}
2: {Id: 22412, Name: "test03", RoleType: "XL Teacher", IsEnrolled: false, EnrolledOn: "", …}
3: {Id: 22413, Name: "test04", RoleType: "End user", IsEnrolled: false, EnrolledOn: "", …}

由于与附加先前的对象列表相关的性能开销,上述方法效率低下。是否可以在下面代码中提到的第一个位置消除重复项

Array.prototype.push.apply($scope.distinctCourseUsers,response); 

您将如何减少代码以使其足够高效以获得上述结果?

【问题讨论】:

    标签: javascript jquery ecmascript-6 ecmascript-2016


    【解决方案1】:

    实际上做了一个blog post on this recently,非常简单。我在这里为您提供了多种选择,因此请确保您坚持到底。​​p>

    您可以使用Arrays 和Set 来获得独特的物品。这是使用简单值的基本思想。

    const arr = [19,22,7,12,6,85];
    const arr2 = [22,8,3,19,45];
    const newArr = [...arr, ...arr2];
    // newArr equals [19, 22, 7, 12, 6, 85, 22, 8, 3, 19, 45]
    const uniqueArr =  = Array.from(new Set(newArr));
    // uniqueArr equals [19, 22, 7, 12, 6, 85, 8, 3, 45]
    

    重要的是要记住对象是按引用的,所以如果你有两个看起来相同(结构上)的对象并不意味着它们是“相同的”,所以在使用 Set 时要考虑这一点。但是,如果对象被 ref 推送到每个数组,那么这仍然对您有用。如果对象 ref 有问题(完全有问题),那么您可能需要一个中介。

    const intermediary = [...myTrueVar];
    intermediary.push(myObj);
    const keys = itermediary.map((it) => it.key));
    const uniqueKeys = Array.from(new Set(keys));
    myTrueVar = intermediary.filter((it) => uniqueKeys.includes(it.key))
    

    或者,你可能真的很疯狂

    const intermediary = [...myTrueVar];
    intermediary.push(myObj)
    const stringed = intermediary.map((it) => JSON.stringify(it));
    myTrueVar = Array.from(new Set(stringed)).map((it) => JSON.parse(it));
    

    但这可能有点矫枉过正,并且可能假设对象键始终处于相同的顺序,因此第一位中介可能是更好的选择(并且可能开销更​​小)。

    还请记住,虽然 IE 11 支持 Set 构造函数,但 Array.from 不支持(解构更是如此),所以如果你被困在过去,你需要将它转换为通天塔。

    或者,您可以简单地检查您的初始数组中的项目,并在必要时有条件地添加它。可能是性能最高的,因为您一次只能添加一个用户。

    !$scope.distinctCourseUsers.find((user) => user.Id === response.Id) &&
      $scope.distinctCourseUsers.push(response)
    

    【讨论】:

      猜你喜欢
      • 2021-09-19
      • 2016-05-07
      • 2018-04-01
      • 2022-12-06
      • 1970-01-01
      • 2013-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多