使用 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 函数(lodashunderscore)与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.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);

【讨论】:

【参考方案10】:

有很多方法可以得到你想要的结果。让我们将它们分类:

仅限 ES6 值

主要方法是Object.values。但是使用Object.keysArray.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将对象值(字符串)转换为数字

如何将 lodash 对象(过滤器对象)动态转换为 jquery listview

使用传播将数组映射到对象

使用map方法将javascript对象数组转换为其他对象数组[重复]

laravel怎么把对象转换为数组

使用 ramda 将数组数组转换为数组对象