使用 lodash 将对象转换为数组
Posted
技术标签:
【中文标题】使用 lodash 将对象转换为数组【英文标题】:transform object to array with lodash 【发布时间】:2014-08-31 17:10:21 【问题描述】:如何使用 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...]
【问题讨论】:
@Mritunjay 是的,因为文档对图书馆有很好的概述......不是。这只是一个详尽的功能列表,如果没有一个功能,遍历每个功能很可能会浪费时间。这个问题很公平。 【参考方案1】:你可以的
var arr = _.values(obj);
有关文档,请参阅here.
【讨论】:
如果您想将密钥保留为属性怎么办? (在本例中,如果id
属性不存在,而您想根据每个对象的键创建它。
你可以这样做:var arr = _.values(_.mapKeys(obj, function(value, key) value.id = key; return value; ));
@DanielSchmidt 我不确定我做错了什么,但该样本只为我返回了 1 行。 :( 所以我所做的是将return
值手动推送到这样的数组中:const divisionsList = []; _.mapKeys(divisions, (value, key) => divisionsList[key] = value; );
我将不胜感激任何改进这种方法的 cmets 或建议。
@JohnnyQ 我认为您需要使用 mapValues 来代替,例如const toArrayWithKey = (obj, keyAs) => _.values(_.mapValues(obj, (value, key) => value[keyAs] = key; return value; ));
@orjan 是的,我确实想通了,只是忘记更新了。谢谢你。【参考方案2】:
_.toArray(obj);
输出为:
[
"name": "Ivan",
"id": 12,
"friends": [
2,
44,
12
],
"works":
"books": [],
"films": []
,
"name": "John",
"id": 22,
"friends": [
5,
31,
55
],
"works":
"books": [],
"films": []
]"
【讨论】:
_.toArray() 工作正常@jivings 仅获取值是一个不错的选择,但在toArray
中,如果需要,无法保留密钥。【参考方案3】:
如果您希望将键(在本例中为 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
【讨论】:
【参考方案4】:如果有人感兴趣,请提供现代原生解决方案:
const arr = Object.keys(obj).map(key => ( key, value: obj[key] ));
或(不是 IE):
const arr = Object.entries(obj).map(([key, value]) => ( key, value ));
【讨论】:
为什么不只是Object.keys(obj).map(key=>(key,value: obj[key]))
我喜欢它甚至没有用户 lodash,干得好,先生!
@Dominic 现在您更改了完整答案并从我的评论中获取,即使没有提及(您已将其编辑掉)。干得好???
@KoushikChatterjee 将其添加回来
这会更有帮助吗? const arr = Object.keys(obj).map(id => ( id, ...obj[id] ));
这会将整个对象带入返回的数据中,不是吗? (使用“id”,因为最初的提问者想将他的密钥存储为 id 道具)【参考方案5】:
var arr = _.map(obj)
您也可以将_.map
函数(lodash
和underscore
)与object
一起使用,它会在内部处理这种情况,用您的迭代对象遍历每个值和键,最后返回一个数组.事实上,如果你只想要一个值数组,你可以在没有任何迭代的情况下使用它(只是_.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>
但是,如果您想转换您的对象,您可以这样做,即使您需要保留密钥,您也可以这样做 (_.map(obj, (v, k) => ...
),并在 map
中添加额外的参数,然后按照您的意愿使用它。
但是,还有其他 Vanilla JS 解决方案(因为每个 lodash
解决方案都应该是纯 JS 版本),例如:
Object.keys
然后map
他们到价值观
Object.values
(在 ES-2017 中)
Object.entries
然后 map
每个键/值对(在 ES-2017 中)
for...in
循环并使用每个键来获取值
还有更多。但是由于这个问题是针对lodash
的(并且假设有人已经在使用它),那么如果没有找到这些,您不需要考虑太多关于版本、方法支持和错误处理的问题。
还有其他 lodash 解决方案,例如 _.values
(对于特定目的更具可读性),或者先获取对然后再映射等。但是如果您的代码需要灵活性,您可以在将来更新它,因为您需要保留 keys
或稍微转换值,那么最好的解决方案是使用单个 _.map
作为此答案中的地址。根据可读性,这也不会那么困难。
【讨论】:
不错,很简单,最简洁。【参考方案6】:2017 年更新:Object.values、lodash values 和 toArray 这样做。并保留键 map 和 spread operator 玩得好:
// 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>
【讨论】:
【参考方案7】:对我来说,这很有效:
_.map(_.toPairs(data), d => _.fromPairs([d]));
转了
"a":"b", "c":"d", "e":"f"
进入
["a":"b", "c":"d", "e":"f"]
【讨论】:
我需要将一个对象转换为一个数组,以使原始对象的每个键/值都是数组中的一个 key:value 对象。 _.toPairs(data) 获取对象 "a":"b", "c":"d", "e":"f" 并将其作为数组返回,例如 [["a":" b"]、["c":"d"]、["e":"f"]]。 _.fromPairs 则相反,它接受一个包含 2 个元素的数组:["a","b"] 并将其作为对象返回:"a":"b"。使用 _.map 我迭代了数组 if 由 _.toPairs 创建的数组,在 _.fromPairs 的帮助下将其转换为对象数组。 我很高兴我向下滚动看到这个。您的解决方案对我有用!谢谢! @NoNine 不需要在数组(数组的)上应用map,可以直接应用在输入对象上,返回每个键值对_.map(data, (v,k)=>([k]: v))
详细看我的回答. _.toPairs
和 _fromPairs
在这里是额外的和不必要的。
这不是问题的意思。因为使用结果有点困难,因为每个条目都包含一个键(您不知道),并且您需要再次为每个单独的条目执行一些逻辑(例如 Object.keys 或 Object.values)以获得值每个,如果玩具想保留键,那么你可以创建一个像[key: 'someKey', val: 'The value', ....,...]
这样结构化的对象数组【参考方案8】:
如果你想要一些自定义的 Object 映射(如原始的 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
_.forEach 的文档https://lodash.com/docs/#forEach
【讨论】:
【参考方案9】:使用纯 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.entries
和 Array#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);
【讨论】:
【参考方案10】:有很多方法可以得到你想要的结果。让我们将它们分类:
仅限 ES6 值:
主要方法是Object.values。但是使用Object.keys 和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 dynamic/computed 属性和 destructuring,您可以保留键并从映射中返回一个对象。
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 键和值:
// 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>
请注意,在上面的示例中使用了 ES6(箭头函数和动态属性)。
如果 ES6 有问题,您可以使用 lodash _.fromPairs
和其他方法来组合对象。
【讨论】:
【参考方案11】:对象到数组
在所有答案中,我认为这是最好的:
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)
。
【讨论】:
以上是关于使用 lodash 将对象转换为数组的主要内容,如果未能解决你的问题,请参考以下文章
如何将 lodash 对象(过滤器对象)动态转换为 jquery listview