【问题标题】:Combine nested arrays into one?将嵌套数组合并为一个?
【发布时间】:2015-04-29 21:37:43
【问题描述】:

假设我有一个与此类似的对象数组:

[
   {
     id: ...,
     name: "...",
     users: [1, 2, 3]
    },
    ...
]

有没有一种方法可以轻松地将每个对象的 .users 数组合并到一个数组中?

【问题讨论】:

    标签: javascript arrays underscore.js lodash


    【解决方案1】:

    Pluck 'n' flatten 会做你想做的事:

    var result = _.flatten(_.pluck(data, 'users'));
    

    编辑

    正如 Richard 所指出的,pluck 在 4.0.0 版中已从 lodash 中删除,但在撰写本文时 (1.8.3) 仍保留在当前版本的下划线中。

    用 map 替换 pluck 对 lodash 和下划线都有效:

    var result = _.flatten(_.map(data, 'users'));
    

    【讨论】:

    • 这是最简单的解决方案。
    • 现在是 var result = .flatten(.map(data, 'users'));由于 pluck 已被弃用并删除。
    • 感谢@RichardLindhout!已编辑答案以反映更改。
    • 当然,_.union(...) 只包含所有唯一 ID。
    【解决方案2】:

    不知道lodash和underscore,但是可以使用Array原生的forEachconcat方法(underscore可能有等价的方法,老浏览器的polyfills)

    var data = [{
         id: ...,
         name: "...",
         users: [1, 2, 3]
        },
        ...
    ];
    var allUsers = [];
    data.forEach(function(obj){
       allUsers = allUsers.concat(obj.users);
    });
    
    console.log(allUsers);
    

    演示

    var data = [{
         id: 1,
         name: "...",
         users: [1, 2, 3]
        },
        {
         id: 2,
         name: "....",
         users: [4, 5, 6]
        },
        {
         id: 3,
         name: "...",
         users: [7, 8, 9]
        },            
    ];
    var allUsers = [];
    data.forEach(function(obj){
       allUsers = allUsers.concat(obj.users);
    });
    
    document.querySelector("#log").innerHTML = allUsers.join(",");
    <div id="log"></div>

    【讨论】:

      【解决方案3】:

      使用 lodash:

      var objects = [
         {
           id: "...",
           name: "...",
           users: [1, 2, 3]
          },
         {
           id: "...",
           name: "...",
           users: [4, 5, 6]
          },
          //...
      ];
      var allUsers = _.flatMap(objects, function(o){return o.users;});
      
      console.log(allUsers);
      // allUsers: [1,2,3,4,5,6]
      <script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>

      【讨论】:

      • 这就是我要找的。谢谢!
      【解决方案4】:

      这将遍历原始数组并返回一个仅包含users 数组值的新数组。我使用Array.prototype.reduce 来保持所有内容都包含在内,但从技术上讲,您也可以使用for 循环来做到这一点。

      var data = [{id: 1, name: "A", users: [1, 2, 3]},
                  {id: 2, name: "B", users: [4, 5, 6]},
                  {id: 3, name: "C", users: [7, 8, 9]}];
      var allUsers = data.reduce(function (result, current) {
          Array.prototype.push.apply(result, current.users);
          return result;
      }, []);
      

      我使用Array.prototype.push 的原因是为了修改现有数组而不是创建多个副本(通过使用Array.prototype.concat 之类的东西)。

      【讨论】:

        【解决方案5】:

        你可以使用Array.prototype.push方法:

        var res = [];
        for (var i = 0; i < o.length; i++) {
           res.push.apply(res, o[i].users);
        }
        

        如果数组应该包含唯一元素:

        res = res.filter(function(val, i, arr) { 
            return arr.indexOf(val) === i;
        });
        

        【讨论】:

        • res.push(o[i].users);
        • @self 创建一个数组数组。
        • 这会导致重复用户。
        • a.push.apply(a, b) 就像a = a.concat(b)
        • 刚刚测试过了。你是对的。不过很奇怪。这似乎是一个 hack
        【解决方案6】:
        var a = [
           {
             id: 1,
             name: "...",
             users: [1, 2, 3]
            },
            ...
        ];
        var res = new Array();
        for(var i = 0; i < a.length; i++) {
            a[i].users.forEach(function(val) { res.push(val); }
        );
        

        【讨论】:

          【解决方案7】:

          这可能不是最有效的,但它会完成你想要的。

          在此处查看小提琴:http://jsfiddle.net/TylersDesk/3x1w8y95/

          var objects = [
              {
                  time: 1234,
                  users: ["Joe", "Bob", "Blake"]
              },
              {
                  time: 1234,
                  users: ["Annie", "Gale"]
              }
          ]
          
          var allUsers = []
          
          for (i=0; i<objects.length; i++) {
              for (key in objects[i]) {
                  if (key === "users") {
                      console.log('found users');
                      console.log(objects[i][key]);
          
                      for (g=0; g<objects[i][key].length; g++) {
                          console.log(objects[i][key][g]);
          
                          //Add to array
                          allUsers.push(objects[i][key][g]);          
                      }
                  }
              }
          }
          
          //Output all users
          console.log(allUsers);
          

          【讨论】:

            猜你喜欢
            • 2017-06-17
            • 1970-01-01
            • 1970-01-01
            • 2018-07-22
            • 2012-09-20
            • 1970-01-01
            • 2019-05-26
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多