将嵌套数组合并为一个?

Combine nested arrays into one?

假设我有一组看起来类似于此的对象:

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

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

您可以使用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;
});

使用 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>

这将遍历原始数组和 return 一个仅包含 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 之类的东西)。

不知道 lodash 或 underscore,但你可以使用 Array 的原生 forEach and concat 方法(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>

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); }
);

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

请参阅此处 fiddle: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);

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

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

编辑

正如 Richard 指出的那样,pluck 在 lodash 4.0.0 版中被删除,但在撰写本文时 (1.8.3) 仍保留在 underscore 的当前版本中。

用 map 替换 pluck 对 lodash 和 underscore 都有效:

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