将包含对象的数组展平为 1 个对象

IT技术 javascript lodash flatten
2021-03-20 04:07:56

给定输入:

[{ a: 1 }, { b: 2 }, { c: 3 }]

如何返回:

{ a: 1, b: 2, c: 3 }

对于数组,lodash不是问题,但这里我们有对象数组。

6个回答

使用Object.assign

let merged = Object.assign(...arr); // ES6 (2015) syntax

var merged = Object.assign.apply(Object, arr); // ES5 syntax

请注意,Object.assign它尚未在许多环境中实现,您可能需要对其进行 polyfill(使用 core-js、另一个 polyfill 或使用 MDN 上的 polyfill)。

您提到了 lodash,因此值得指出的是,它带有一个_.assign用于此目的函数,该函数执行相同的操作:

 var merged = _.assign.apply(_, [{ a: 1 }, { b: 2 }, { c: 3 }]);

但我真的推荐新的标准库方式。

@Bergi 如果我想保留assign完整的输入,我可以如果我不这样做,我当然不必。由于这不是一个要求,我没有这样对待它。
2021-04-29 04:07:56
Expected at least 1 arguments, but got 0 or more.如果我没有添加额外的 {},我的 linter 会抛出一个 Object.assign({}, ...ids.
2021-05-03 04:07:56
你不应该Object.assign({}, ...arr)吗?!
2021-05-06 04:07:56
@BenjaminGruenbaum:是的,保留输入是最佳实践 :-) 当它出乎意料时可能会导致丑陋的错误。
2021-05-07 04:07:56

使用 lodash,您可以使用merge()

var arr = [ { a: 1 }, { b: 2 }, { c: 3 } ];
_.merge.apply(null, [{}].concat(arr));
// → { a: 1, b: 2, c: 3 }

如果你在几个地方这样做,你可以merge()通过使用partial()spread()来更优雅一点

var merge = _.spread(_.partial(_.merge, {}));
merge(arr);
// → { a: 1, b: 2, c: 3 }

这是一个不使用 ES6 方法的版本......

var arr = [{ a: 1 }, { b: 2 }, { c: 3 }];
var obj = {};

for(var i = 0; i < arr.length; i++) {
    var o = arr[i];
    for(var key in o) {
        if(typeof o[key] != 'function'){
            obj[key] = o[key];
        }
    }
}

console.log(obj);

小提琴:http : //jsfiddle.net/yaw3wbb8/

可枚举的属性不是您想要复制的属性吗?例如,您不会想要Array.prototype.length对象中的类似内容.. 对吗?还是我完全错过了这个?
2021-04-23 04:07:56
在 if 语句中添加一个简单的 ` && !o.propertyIsEnumerable(key)` 会解决这个问题吗?
2021-04-24 04:07:56
好吧,因为... in 只枚举可枚举的属性。AObject(o).hasOwnProperty(obj)会修复它(确保它不在原型上) -Object(o)部分是确保我们不会调用不存在的方法,以便例如传递4不会失败(并且不复制任何内容)。
2021-05-03 04:07:56
请注意,这也将复制可枚举的原型属性(在这种特殊情况下这不是问题)。
2021-05-08 04:07:56
@BenjaminGruenbaum:更好的是:Object.prototype.hasOwnProperty.call(o, i)确保我们不会调用自定义方法甚至非函数属性值。
2021-05-10 04:07:56

您可以像这样使用 underscore.extend 函数:

var _ = require('underscore');
var a = [{ a: 1 }, { b: 2 }, { c: 3 }];

var result = _.extend.apply(null, a);
console.log(result); // { a: 1, b: 2, c: 3 }
console.log(a); // [ { a: 1, b: 2, c: 3 }, { b: 2 }, { c: 3 } ]

并防止修改原始数组,您应该使用

var _ = require('underscore');
var a = [{ a: 1 }, { b: 2 }, { c: 3 }];

var result = _.extend.apply(null, [{}].concat(a));
console.log(result); // { a: 1, b: 2, c: 3 }
console.log(a); // [ { a: 1 }, { b: 2 }, { c: 3 } ]

这里可以测试一下

添加到已接受的答案中,使用 ES6 运行代码片段。

let input = [{ a: 1 }, { b: 2 }, { c: 3 }]
//Get input object list with spread operator
console.log(...input)
//Get all elements in one object
console.log(Object.assign(...input))