使用lodash将对象转换为数组

如何用lodash将一个大的object转换为array ?

var obj = {
22: {name:"John", id:22, friends:[5,31,55], works:{books:[], films:[],}
12: {name:"Ivan", id:12, friends:[2,44,12], works:{books:[], films:[],}
}


// transform to
var arr = [{name:"John", id:22...},{name:"Ivan", id:12...}]
251071 次浏览

你可以这样做

var arr = _.values(obj);

有关文档请参见在这里。

_.toArray(obj);

输出为:

[
{
"name": "Ivan",
"id": 12,
"friends": [
2,
44,
12
],
"works": {
"books": [],
"films": []
}
},
{
"name": "John",
"id": 22,
"friends": [
5,
31,
55
],
"works": {
"books": [],
"films": []
}
}
]"

如果您希望键(在本例中为id)作为每个数组项的属性保留,您可以这样做

const arr = _(obj) //wrap object so that you can chain lodash methods
.mapValues((value, id)=>_.merge({}, value, {id})) //attach id to object
.values() //get the values of the result
.value() //unwrap array of objects

一个现代的本地解决方案,如果有人感兴趣:

const arr = Object.keys(obj).map(key => ({ key, value: obj[key] }));

或(不是IE):

const arr = Object.entries(obj).map(([key, value]) => ({ key, value }));

var arr = _.map(obj)

你也可以在object中使用_.map函数(包括lodashunderscore),它将在内部处理这种情况,用迭代对象遍历每个值和键,最后返回一个数组。事实上,如果你只想要一个值数组,你可以不带任何iteratee(只要_.map(obj))使用它。好的部分是,如果你需要中间的任何变换,你可以一次完成。

例子:

var obj = {
key1: {id: 1, name: 'A'},
key2: {id: 2, name: 'B'},
key3: {id: 3, name: 'C'}
};


var array1 = _.map(obj, v=>v);
console.log('Array 1: ', array1);


/*Actually you don't need the callback v=>v if you
are not transforming anything in between, v=>v is default*/


//SO simply you can use
var array2 = _.map(obj);
console.log('Array 2: ', array2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

However, if you want to transform your object you can do so, even if you need to preserve the key, you can do that ( _.map(obj, (v, k) => {...}) with additional argument in map and then use it how you want.

However there are other Vanilla JS solution to this (as every lodash solution there should pure JS version of it) like:

  • Object.keys and then map them to values
  • Object.values (in ES-2017)
  • Object.entries and then map each key/value pairs (in ES-2017)
  • for...in loop and use each keys for feting values

And a lot more. But since this question is for lodash (and assuming someone already using it) then you don't need to think a lot about version, support of methods and error handling if those are not found.

There are other lodash solutions like _.values (more readable for specific perpose), or getting pairs and then map and so on. but in the case your code need flexibility that you can update it in future as you need to preserve keys or transforming values a bit, then the best solution is to use a single _.map as addresed in this answer. That will bt not that difficult as per readability also.

2017年更新:Object.values, lodash toArray做。为了保存键,地图传播算子可以很好地使用:

// import { toArray, map } from 'lodash'
const map = _.map


const input = {
key: {
value: 'value'
}
}


const output = map(input, (value, key) => ({
key,
...value
}))


console.log(output)
// >> [{key: 'key', value: 'value'}])
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

对我来说,这很有效:

_.map(_.toPairs(data), d => _.fromPairs([d]));

结果

{"a":"b", "c":"d", "e":"f"}

[{"a":"b"}, {"c":"d"}, {"e":"f"}]

如果你想要对象到数组的自定义映射(比如原始的Array.prototype.map),你可以使用_.forEach:

let myObject = {
key1: "value1",
key2: "value2",
// ...
};


let myNewArray = [];


_.forEach(myObject, (value, key) => {
myNewArray.push({
someNewKey: key,
someNewValue: value.toUpperCase() // just an example of new value based on original value
});
});


// myNewArray => [{ someNewKey: key1, someNewValue: 'VALUE1' }, ... ];

参见_的lodash doc。forEach https://lodash.com/docs/#forEach

纯JavaScript的(ECMAScript-2016) Object.values转换对象到数组:

var obj = {
22: {name:"John", id:22, friends:[5,31,55], works:{books:[], films:[]}},
12: {name:"Ivan", id:12, friends:[2,44,12], works:{books:[], films:[]}}
}


var values = Object.values(obj)


console.log(values);

如果你还想保留键,使用Object.entriesArray#map,如下所示:

var obj = {
22: {name:"John", id:22, friends:[5,31,55], works:{books:[], films:[]}},
12: {name:"Ivan", id:12, friends:[2,44,12], works:{books:[], films:[]}}
}


var values = Object.entries(obj).map(([k, v]) => ({[k]: v}))


console.log(values);

有很多方法可以达到你想要的效果。让我们把它们分类:

ES6仅限值:

它的主要方法是< >强Object.values < / >强。但是使用< >强种< / >强< >强Array.map < / >强,你也可以得到预期的结果:

Object.values(obj)
Object.keys(obj).map(k => obj[k])

var obj = {
A: {
name: "John"
},
B: {
name: "Ivan"
}
}


console.log('Object.values:', Object.values(obj))
console.log('Object.keys:', Object.keys(obj).map(k => obj[k]))

ES6键&放大器;价值:

使用map和ES6 < >强动态/计算< / >强属性和< >强destructuring < / >强,你可以保留键并从map返回一个对象。

Object.keys(obj).map(k => ({[k]: obj[k]}))
Object.entries(obj).map(([k,v]) => ({[k]:v}))

var obj = {
A: {
name: "John"
},
B: {
name: "Ivan"
}
}


console.log('Object.keys:', Object.keys(obj).map(k => ({
[k]: obj[k]
})))
console.log('Object.entries:', Object.entries(obj).map(([k, v]) => ({
[k]: v
})))

仅限Lodash值:

为此设计的方法是< >强_.values < / >强,但是有像< >强_.map < / >强这样的“快捷方式”和实用方法< >强_.toArray < / >强,它也会从对象中返回包含只有价值观的数组。你也可以通过_.keys _.map,并通过使用obj[key]符号从对象中获取值。

注意:_.map在传递对象时将使用它的< >强baseMap < / >强处理程序,这基本上是对象属性上的forEach

_.values(obj)
_.map(obj)
_.toArray(obj)
_.map(_.keys(obj), k => obj[k])

var obj = {
A: {
name: "John"
},
B: {
name: "Ivan"
}
}


console.log('values:', _.values(obj))
console.log('map:', _.map(obj))
console.log('toArray:', _.toArray(obj))
console.log('keys:', _.map(_.keys(obj), k => obj[k]))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

Lodash Key & Value:

// Outputs an array with [[KEY, VALUE]]
_.entries(obj)
_.toPairs(obj)


// Outputs array with objects containing the keys and values
_.map(_.entries(obj), ([k,v]) => ({[k]:v}))
_.map(_.keys(obj), k => ({[k]: obj[k]}))
_.transform(obj, (r,c,k) => r.push({[k]:c}), [])
_.reduce(obj, (r,c,k) => (r.push({[k]:c}), r), [])

var obj = {
A: {
name: "John"
},
B: {
name: "Ivan"
}
}


// Outputs an array with [KEY, VALUE]
console.log('entries:', _.entries(obj))
console.log('toPairs:', _.toPairs(obj))


// Outputs array with objects containing the keys and values
console.log('entries:', _.map(_.entries(obj), ([k, v]) => ({
[k]: v
})))
console.log('keys:', _.map(_.keys(obj), k => ({
[k]: obj[k]
})))
console.log('transform:', _.transform(obj, (r, c, k) => r.push({
[k]: c
}), []))
console.log('reduce:', _.reduce(obj, (r, c, k) => (r.push({
[k]: c
}), r), []))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

Note that in the above examples ES6 is used (arrow functions and dynamic properties). You can use lodash _.fromPairs and other methods to compose an object if ES6 is an issue.

对象到数组

在所有的答案中,我认为这个是最好的:

let arr = Object.entries(obj).map(([key, val]) => ({ key, ...val }))

转换:

{
a: { p: 1, q: 2},
b: { p: 3, q: 4}
}

:

[
{ key: 'a', p: 1, q: 2 },
{ key: 'b', p: 3, q: 4 }
]

数组到对象

变回来:

let obj = arr.reduce((obj, { key, ...val }) => { obj[key] = { ...val }; return obj; }, {})

将键保留在值中进行反向转换:

let obj = arr.reduce((obj, { key, ...val }) => { obj[key] = { key, ...val }; return obj; }, {})

将:

{
a: { key: 'a', p: 1, q: 2 },
b: { key: 'b', p: 3, q: 4 }
}

对于最后一个例子,你也可以使用lodash _.keyBy(arr, 'key')_.keyBy(arr, i => i.key)