使用lodash将对象转换为数组

时间:2014-07-10 10:49:17

标签: javascript arrays object 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...}]

谢谢!

11 个答案:

答案 0 :(得分:212)

你可以做到

var arr = _.values(obj);

有关文档,请参阅here.

答案 1 :(得分:33)

_.toArray(obj);

输出为:

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

答案 2 :(得分:19)

对我来说,这很有效:

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

转为

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

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

答案 3 :(得分:18)

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

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

感谢@KoushikChatterjee的改进

答案 4 :(得分:11)

如果您希望将密钥(在本例中为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

答案 5 :(得分:7)

2017年更新:Object.values,lodash valuestoArray这样做。并保留密钥mapspread 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>
&#13;
&#13;
&#13;

答案 6 :(得分:7)

使用纯JavaScript的ECMAScript-2016Object.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);

答案 7 :(得分:5)

var arr = _.map(obj)

您可以_.map同时使用lodashunderscore object功能,它将在内部处理该情况,迭代每个值并使用你的iteratee,最后返回一个数组。事实上,如果您只想要一组值,则可以在没有任何迭代(仅_.map(obj))的情况下使用它。好的一面是,如果你需要进行任何转换,你可以一次性完成。

示例:

&#13;
&#13;
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);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
&#13;
&#13;
&#13;

但是,如果你想转换你的对象,你可以这样做,即使你需要保留密钥,你可以在_.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作为补充。根据可读性,这并不困难。

答案 8 :(得分:3)

如果您想将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' }, ... ];

请参阅_ {forEach https://lodash.com/docs/#forEach

lodash doc

答案 9 :(得分:3)

有很多方法可以得到想要的结果。让我们将其分为以下类别:

仅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键和值

使用地图和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,它们也将返回仅包含值的数组。强>从对象。您也可以通过_.map _.keys并使用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和其他方法来组成对象。

答案 10 :(得分:0)

对象到数组

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

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)