【问题标题】:Compare two object arrays and combine missing objects比较两个对象数组并合并缺失的对象
【发布时间】:2016-05-07 06:32:43
【问题描述】:

我有 2 个对象数组。第一个是一组经理。第二个是从第一个数组中选择的管理器数组。不同的是我添加了一个属性selected: true。我现在需要用选定的经理替换第一个数组中的经理。我正在使用我创建的 AngularJS 服务来执行此操作。我确信有更简单的解决方案,所以我愿意接受建议。 JavaScript、jQuery、lodash、LINQ.js 都不错。 我有一个 plunker,我已经显示了我需要的结果。请注意没有selected:true 属性的经理。

plunker

var app = angular.module("mainModule", []);
var MainController = function($scope, service) {

var eventUsers = [
  {
    "event_Users_ID":1009,"event_ID":11,"user_ID":"15e640c1-a481-4997-96a7-be2d7b3fcabb"
  },{
    "event_Users_ID":1010,"event_ID":11,"user_ID":"250a19be-e661-4c04-9a50-c84b0e7349b7"
  },{
   "event_Users_ID":1011,"event_ID":11,"user_ID":"4cada7f0-b961-422d-8cfe-4e96c1fc11dd"
  },{
   "event_Users_ID":1013,"event_ID":11,"user_ID":"a3125317-5deb-426d-bbb1-06d3bd4ebaa6"
  }];
 var managers = [
   {
    "id": "15e640c1-a481-4997-96a7-be2d7b3fcabb",
    "fullName": "Kul Srivastva"
   },{
    "id": "250a19be-e661-4c04-9a50-c84b0e7349b7",
    "fullName": "Todd Brothers"
   }, {
    "id": "4cada7f0-b961-422d-8cfe-4e96c1fc11dd",
    "fullName": "Rudy Sanchez"
   }, {
    "id": "79823c6d-de52-4464-aa7e-a15949fb25fb",
    "fullName": "Mike Piehota",
   }, {
    "id": "a3125317-5deb-426d-bbb1-06d3bd4ebaa6",
    "fullName": "Nick Broadhurst"
  }];                

   $scope.result = service.eventUserMatch(eventUsers, managers);
 };

  function service() {
    var vm = this;

    vm.eventUserMatch = function (eventUsers, managers) {
        var arry = [];
        arry = $.map(eventUsers, function (eventUser) {
            var manager = $.grep(managers, function (user) {
                return user.id === eventUser.user_ID;
            })[0];

            eventUser.id = manager.id;
            eventUser.fullName = manager.fullName;
            eventUser.selected = true;
            return eventUser;
        });
        return arry;
    };
 }

app.controller("MainController", MainController);
app.service('service', service);

【问题讨论】:

  • 非常混乱的问题描述。您要解决的更高级别的用例和问题是什么?
  • 你试过什么?没有选择的经理怎么办:true?????您说“请注意没有 'selected:true' 属性的经理”但没有解释这是关于什么的。
  • 是的,抱歉,我很难寻求帮助,因为我无法很好地解释。给我一分钟,我会解释整体情况
  • 我想我明白了您要完成的工作....您可以遍历新的 Selected Managers 数组并使用 lodash 的 findByIndex 方法在 Selected Manager Array 中搜索每个经理第一个管理器数组,如果找到索引,将第一个数组中的管理器替换为第二个数组中循环当前目标的管理器? lodash.com/docs#findIndex
  • 据我了解您想要实现的目标:循环遍历eventUsers,如果eventUsers[i].user_ID 等于managers[j].id,则将属性"selected" : true 添加到managers[j]。对吗?

标签: javascript jquery angularjs lodash linq.js


【解决方案1】:

您可以使用Array#map

// Get all the event user IDs in an array
var eventUserIds = eventUsers.map(e => e.user_ID);

// Iterate over managers
managers = managers.map(e => {
    // If manager is present in the event users, `select` it
    if (eventUserIds.indexOf(e.id) !== -1) {
        e.selected = true;
    }

    return e;
});

var eventUsers = [{
    "event_Users_ID": 1009,
    "event_ID": 11,
    "user_ID": "15e640c1-a481-4997-96a7-be2d7b3fcabb"
}, {
    "event_Users_ID": 1010,
    "event_ID": 11,
    "user_ID": "250a19be-e661-4c04-9a50-c84b0e7349b7"
}, {
    "event_Users_ID": 1011,
    "event_ID": 11,
    "user_ID": "4cada7f0-b961-422d-8cfe-4e96c1fc11dd"
}, {
    "event_Users_ID": 1013,
    "event_ID": 11,
    "user_ID": "a3125317-5deb-426d-bbb1-06d3bd4ebaa6"
}];


var managers = [{
    "id": "15e640c1-a481-4997-96a7-be2d7b3fcabb",
    "fullName": "Kul Srivastva"
}, {
    "id": "250a19be-e661-4c04-9a50-c84b0e7349b7",
    "fullName": "Todd Brothers"
}, {
    "id": "4cada7f0-b961-422d-8cfe-4e96c1fc11dd",
    "fullName": "Rudy Sanchez"
}, {
    "id": "79823c6d-de52-4464-aa7e-a15949fb25fb",
    "fullName": "Mike Piehota",
}, {
    "id": "a3125317-5deb-426d-bbb1-06d3bd4ebaa6",
    "fullName": "Nick Broadhurst"
}];

var eventUserIds = eventUsers.map(e => e.user_ID);
managers = managers.map(e => {
    if (eventUserIds.indexOf(e.id) !== -1) {
        e.selected = true;
    }

    return e;
})

console.log(managers);
document.getElementById('result').innerHTML = JSON.stringify(managers, 0, 4);
<pre id="result"></pre>

【讨论】:

    【解决方案2】:

    这行得通吗?循环遍历新的管理器数组,使用旧管理器数组中匹配管理器对象的 lodash 查找索引,如果找到,则将旧管理器数组中的旧管理器替换为新管理器数组中的管理器?

    可能有一种更有效的方法来编写解决方案,但假设我正确理解了您的问题,我相信这应该可行吗?我目前正在工作,无法测试。

    for(var i=0; i < SelectedManagersArray.length; i++){
        var index = _.findIndex(OldManagersArray, {id: SelectedManagersArray[i].id, fullName: selectedManagersArray[i].fullName);
    //I believe lodash returns a -1 if a matching index isn't found.
        if(index !== -1){SelectedManagersArray[index] = OldManagersArray[i]}
        }
    

    【讨论】:

    • 实际上可以通过使用像 Freeeeez 建议的方法并像我在代码中写的那样找到索引并基本上说 if(index !== 1){SelectedManagersArray[index].selected = true }。可能是一种更好的方法,因为用来自不同地方的其他对象替换对象可能会因为通过引用而不是值传递而变得混乱。
    • 如果你使用 lodash,那么在任何地方都使用它,例如forEach 而不是 for。另一方面,只为几串代码使用如此庞大的库是没有意义的。
    【解决方案3】:

    简单实现:

    for(var i = 0; i < eventUsers.length; i++) {    
        for(var j = 0; j < managers.length; j++) {
            if(eventUsers[i].user_ID === managers[j].id) {
                managers[j].selected = true;
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      正如你所说,我确实认为可能有更简单的方法来做到这一点。

      我建议你看一下SugarJs,它是一个 JavaScript 库,它使用非常有用的方法扩展了本机对象。 在您的情况下,Arrays 上的文档。

      对我来说,处理大量原生 JavaScript 对象 (JSON) 很有帮助。

      【讨论】:

      • @Tushar StackOverflow 上的新功能,感谢您帮助编辑答案,感谢!下次注意(降噪;布局;))
      猜你喜欢
      • 2020-08-28
      • 2022-12-06
      • 1970-01-01
      • 1970-01-01
      • 2021-09-19
      • 2021-10-13
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多