使用lodash将对象转换为数组

sia*_*olt 144 javascript arrays object lodash

我怎样才能改变一个大objectarray与lodash?

例:

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...}]
Run Code Online (Sandbox Code Playgroud)

谢谢!

Dan*_*idt 235

你可以做

var arr = _.values(obj);
Run Code Online (Sandbox Code Playgroud)

有关文档,请参阅此处

  • 如果你想将密钥保存为属性怎么办?(在此示例中,如果`id`属性不存在,并且您希望基于每个对象的键创建它. (29认同)
  • 你可以这样做:`var arr = _.values(_.mapKeys(obj,function(value,key){value.id = key; return value;}));` (8认同)
  • @JohnnyQ我认为你需要使用mapValues,例如`const toArrayWithKey =(obj,keyAs)=> _.values(_.mapValues(obj,(value,key)=> {value [keyAs] = key; return值;}));` (7认同)
  • @DanielSchmidt 我不确定我做错了什么,但该示例只为我返回了 1 行。:( 所以我所做的就是手动将 `return` 值推送到一个数组,如下所示: `const divergesList = []; _.mapKeys(divisions, (value, key) => { divergenceList[key] = value; }) ;` 如果有任何意见或建议来改进这种方法,我将不胜感激。 (2认同)

Jiv*_*ngs 37

_.toArray(obj);
Run Code Online (Sandbox Code Playgroud)

输出为:

[
  {
    "name": "Ivan",
    "id": 12,
    "friends": [
      2,
      44,
      12
    ],
    "works": {
      "books": [],
      "films": []
    }
  },
  {
    "name": "John",
    "id": 22,
    "friends": [
      5,
      31,
      55
    ],
    "works": {
      "books": [],
      "films": []
    }
  }
]"
Run Code Online (Sandbox Code Playgroud)

  • 对于仅获取值,这是一个不错的选择,但是在`toArray`中,如果需要的话,无法保留键。 (2认同)

Dom*_*nic 23

如果有兴趣,现代原生解决方案:

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

感谢@KoushikChatterjee的改进

  • 为什么不只是`Object.keys(obj).map(key =>({key,value:obj [key]})))` (2认同)
  • 这会更有用吗?``const arr = Object.keys(obj).map(id =>({id,... obj [id]})));```会将整个对象带入返回的数据中吗?(使用“ id”,因为原始提问者想将其密钥存储为id道具) (2认同)

小智 19

对我来说,这工作:

_.map(_.toPairs(data), d => _.fromPairs([d]));
Run Code Online (Sandbox Code Playgroud)

事实证明

{"a":"b", "c":"d", "e":"f"} 
Run Code Online (Sandbox Code Playgroud)

[{"a":"b"}, {"c":"d"}, {"e":"f"}]
Run Code Online (Sandbox Code Playgroud)


Sel*_*jwa 12

如果您希望将密钥(在本例中为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
Run Code Online (Sandbox Code Playgroud)


Akr*_*ion 9

有很多方法可以得到您想要的结果。让我们按类别细分它们:

仅ES6值

主要方法是Object.values。但是使用Object.keysArray.map您也可以达到预期的结果:

Object.values(obj)
Object.keys(obj).map(k => obj[k])
Run Code Online (Sandbox Code Playgroud)

Object.values(obj)
Object.keys(obj).map(k => obj[k])
Run Code Online (Sandbox Code Playgroud)

ES6关键和价值

使用地图和ES6 动态/计算属性并进行销毁,您可以保留键并从地图返回对象。

Object.keys(obj).map(k => ({[k]: obj[k]}))
Object.entries(obj).map(([k,v]) => ({[k]:v}))
Run Code Online (Sandbox Code Playgroud)

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]))
Run Code Online (Sandbox Code Playgroud)

仅Lodash值

_.values但是,为此设计的方法有“快捷方式”之类_.map的实用程序方法_.toArray,该方法也将返回包含对象的数组。你也可以_.map尽管_.keys和使用得到的对象中的值obj[key]符号。

注意:_.map传递对象时,将使用其baseMap处理程序,该处理程序基本上forEach是对象属性。

_.values(obj)
_.map(obj)
_.toArray(obj)
_.map(_.keys(obj), k => obj[k])
Run Code Online (Sandbox Code Playgroud)

Object.keys(obj).map(k => ({[k]: obj[k]}))
Object.entries(obj).map(([k,v]) => ({[k]:v}))
Run Code Online (Sandbox Code Playgroud)
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
})))
Run Code Online (Sandbox Code Playgroud)

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), [])
Run Code Online (Sandbox Code Playgroud)

_.values(obj)
_.map(obj)
_.toArray(obj)
_.map(_.keys(obj), k => obj[k])
Run Code Online (Sandbox Code Playgroud)
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]))
Run Code Online (Sandbox Code Playgroud)

请注意,在以上示例中使用了ES6(箭头功能和动态属性)。_.fromPairs如果存在ES6问题,则可以使用lodash 和其他方法来组成对象。


ora*_*rad 9

对象到数组

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

let arr = Object.entries(obj).map(([key, val]) => ({ key, ...val }))
Run Code Online (Sandbox Code Playgroud)

转换:

{
  a: { p: 1, q: 2},
  b: { p: 3, q: 4}
}
Run Code Online (Sandbox Code Playgroud)

到:

[
  { key: 'a', p: 1, q: 2 }, 
  { key: 'b', p: 3, q: 4 }
]
Run Code Online (Sandbox Code Playgroud)

数组到对象

变回:

let obj = arr.reduce((obj, { key, ...val }) => { obj[key] = { ...val }; return obj; }, {})
Run Code Online (Sandbox Code Playgroud)

要转换回保留值中的键:

let obj = arr.reduce((obj, { key, ...val }) => { obj[key] = { key, ...val }; return obj; }, {})
Run Code Online (Sandbox Code Playgroud)

会给:

{
  a: { key: 'a', p: 1, q: 2 },
  b: { key: 'b', p: 3, q: 4 }
}
Run Code Online (Sandbox Code Playgroud)

对于最后一个示例,您还可以使用 lodash_.keyBy(arr, 'key')_.keyBy(arr, i => i.key).


Vla*_*nev 7

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'}])
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
Run Code Online (Sandbox Code Playgroud)


Bla*_*ard 7

使用纯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);
Run Code Online (Sandbox Code Playgroud)

如果你还想保持密钥的使用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);
Run Code Online (Sandbox Code Playgroud)


Kou*_*jee 5

var arr = _.map(obj)

您也可以使用_.map(lodashunderscore)的函数object,它将在内部处理该情况,迭代每个值并使用您的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);
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
Run Code Online (Sandbox Code Playgroud)

但是,如果要转换对象,则可以执行此操作,即使需要保留键,也可以_.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(对于特定的perpose更具可读性),或者获得对,然后映射等等.但是如果你的代码需要灵活性,你可以在将来更新它,因为你需要keys稍微保留或转换值,那么最好的解决方案是_.map在这个答案中使用单个asreresed.根据可读性,这也不会那么困难.

  • 很好,非常简单,最简洁. (2认同)