使用map()和Iterator将对象数组分离为多个数组的JavaScript方法

10
  1. 基本上我有一个对象数组,例如

    var array = [{x: 10, y: 5, r: 10, ...} ]

对象中还有更多的字段,但是为了简洁起见,这里是将字段分离到数组中的方法:

var x = array.map(obj => obj.x);
var y = array.map(obj => obj.y);
// and so on for each field

功能可以实现,但随着字段数量和数组大小的增长,该方法看起来非常低效,因为它会多次扫描数组。我可以使用标准循环,但在这种情况下,我更喜欢使用map(),因为我认为它更易读。 是否可以从map中返回多个值? 我认为应该这样:

var [x, y] = array.map(obj => [obj.x, obj.y]); // should output two arrays

或者任何类似于可读性的东西(在我看来,减少会更不易读)。

  1. 我注意到一些更新的JavaScript函数,例如array.entries(),它返回一个迭代器对象。我如何实现这样的函数?

所有的对象都包含相同的键吗? - ibrahim mahrir
3个回答

7
您可以缩小数组并迭代对象键/值对。然后将该属性的值推送到数组中。

var array = [{ x: 10, y: 5, r: 10 }, { x: 11, y: 6, r: 11 }],
    result = array.reduce((r, o) => {
        Object.entries(o).forEach(([k, v]) => (r[k] = r[k] || []).push(v));
        return r;
    }, Object.create(null));
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }


6
所以,你第二次尝试是正确的开始:
var [x, y] = array.map(obj => [obj.x, obj.y]);

正如您所指出的,第一次尝试效率太低,因为您需要循环遍历数组多次,以获取想要提取的每个字段,但是您可以使用数组的.reduce()方法完成您想要做的一切。

我会按照以下方式操作:

var [x, y] = array.reduce(
    (accum, val) => {
        accum[0].push(val.x);
        accum[1].push(val.y);
        return accum;
    },
    [ [], [] ]
);

我所做的是告诉reducer使用空数组的空数组([ [], [] ])初始化累加器,当循环遍历数组时,它将把.x属性放入累加器中的第一个数组中,并将.y属性放入第二个数组中。由于解构的存在,x将是所有.x属性的数组,y将是所有.y属性的数组。这种方法易于扩展,只需向初始累加器对象添加更多的空数组,并确保在reducer中将这些字段推入该新对象即可。

2
如何使其通用化?即不仅适用于两个属性。 - user3599803

0
如果所有对象都具有相同的键,则可以获取这些键的副本并缓存,以便您不需要为每个对象获取它们。然后,您可以使用这些键来初始化结果对象,然后循环数组并将值推入数组中,如下所示:
var keys = Object.keys(array[0]);                          // get the keys of the first object (assuming all objects have the same keys)
var result = {};                                           // the result object (you can use the safe Object.create(null) instead of {})

keys.forEach(key => result[key] = []);                     // initialize the result object (make an empty array entry for each key in keys)

array.forEach(obj =>                                       // for each object in array
  keys.forEach(key => result[key].push(obj[key]))          // add the values of this object to their corresponding array from result using keys from the array keys
);

演示:

var array = [{ x: 10, y: 5, r: 10 }, { x: 11, y: 6, r: 11 }];

var keys = Object.keys(array[0]);
var result = {};

keys.forEach(key => result[key] = []);

array.forEach(obj =>
  keys.forEach(key => result[key].push(obj[key]))
);
    
console.log(result);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接