Related
I have an array of objects:
[
{ key : '11', value : '1100', $$hashKey : '00X' },
{ key : '22', value : '2200', $$hashKey : '018' }
];
How do I convert it into the following by JavaScript?
{
"11": "1100",
"22": "2200"
}
Tiny ES6 solution can look like:
var arr = [{key:"11", value:"1100"},{key:"22", value:"2200"}];
var object = arr.reduce(
(obj, item) => Object.assign(obj, { [item.key]: item.value }), {});
console.log(object)
Also, if you use object spread, than it can look like:
var object = arr.reduce((obj, item) => ({...obj, [item.key]: item.value}) ,{});
One more solution that is 99% faster is(tested on jsperf):
var object = arr.reduce((obj, item) => (obj[item.key] = item.value, obj) ,{});
Here we benefit from comma operator, it evaluates all expression before comma and returns a last one(after last comma). So we don't copy obj each time, rather assigning new property to it.
This should do it:
var array = [
{ key: 'k1', value: 'v1' },
{ key: 'k2', value: 'v2' },
{ key: 'k3', value: 'v3' }
];
var mapped = array.map(item => ({ [item.key]: item.value }) );
var newObj = Object.assign({}, ...mapped );
console.log(newObj );
One-liner:
var newObj = Object.assign({}, ...(array.map(item => ({ [item.key]: item.value }) )));
You're probably looking for something like this:
// original
var arr = [
{key : '11', value : '1100', $$hashKey : '00X' },
{key : '22', value : '2200', $$hashKey : '018' }
];
//convert
var result = {};
for (var i = 0; i < arr.length; i++) {
result[arr[i].key] = arr[i].value;
}
console.log(result);
I like the functional approach to achieve this task:
var arr = [{ key:"11", value:"1100" }, { key:"22", value:"2200" }];
var result = arr.reduce(function(obj,item){
obj[item.key] = item.value;
return obj;
}, {});
Note: Last {} is the initial obj value for reduce function, if you won't provide the initial value the first arr element will be used (which is probably undesirable).
https://jsfiddle.net/GreQ/2xa078da/
Using Object.fromEntries:
const array = [
{ key: "key1", value: "value1" },
{ key: "key2", value: "value2" },
];
const obj = Object.fromEntries(array.map(item => [item.key, item.value]));
console.log(obj);
A clean way to do this using modern JavaScript is as follows:
const array = [
{ name: "something", value: "something" },
{ name: "somethingElse", value: "something else" },
];
const newObject = Object.assign({}, ...array.map(item => ({ [item.name]: item.value })));
// >> { something: "something", somethingElse: "something else" }
you can merge array of objects in to one object in one line:
const obj = Object.assign({}, ...array);
Use lodash!
const obj = _.keyBy(arrayOfObjects, 'keyName')
Update: The world kept turning. Use a functional approach instead.
Previous answer
Here you go:
var arr = [{ key: "11", value: "1100" }, { key: "22", value: "2200" }];
var result = {};
for (var i=0, len=arr.length; i < len; i++) {
result[arr[i].key] = arr[i].value;
}
console.log(result); // {11: "1000", 22: "2200"}
Simple way using reduce
// Input :
const data = [{key: 'value'}, {otherKey: 'otherValue'}];
data.reduce((prev, curr) => ({...prev, ...curr}) , {});
// Output
{key: 'value', otherKey: 'otherValue'}
More simple Using Object.assign
Object.assign({}, ...array);
Using Underscore.js:
var myArray = [
Object { key="11", value="1100", $$hashKey="00X"},
Object { key="22", value="2200", $$hashKey="018"}
];
var myObj = _.object(_.pluck(myArray, 'key'), _.pluck(myArray, 'value'));
Nearby 2022, I like this approach specially when the array of objects are dynamic which also suggested based on #AdarshMadrecha's test case scenario,
const array = [
{ key : '11', value : '1100', $$hashKey : '00X' },
{ key : '22', value : '2200', $$hashKey : '018' }];
let obj = {};
array.forEach( v => { obj[v.key] = v.value }) //assign to new object
console.log(obj) //{11: '1100', 22: '2200'}
let array = [
{ key: "key1", value: "value1" },
{ key: "key2", value: "value2" },
];
let arr = {};
arr = array.map((event) => ({ ...arr, [event.key]: event.value }));
console.log(arr);
Was did yesterday
// Convert the task data or array to the object for use in the above form
const {clientData} = taskData.reduce((obj, item) => {
// Use the clientData (You can set your own key name) as the key and the
// entire item as the value
obj['clientData'] = item
return obj
}, {});
Here's how to dynamically accept the above as a string and interpolate it into an object:
var stringObject = '[Object { key="11", value="1100", $$hashKey="00X"}, Object { key="22", value="2200", $$hashKey="018"}]';
function interpolateStringObject(stringObject) {
var jsObj = {};
var processedObj = stringObject.split("[Object { ");
processedObj = processedObj[1].split("},");
$.each(processedObj, function (i, v) {
jsObj[v.split("key=")[1].split(",")[0]] = v.split("value=")[1].split(",")[0].replace(/\"/g,'');
});
return jsObj
}
var t = interpolateStringObject(stringObject); //t is the object you want
http://jsfiddle.net/3QKmX/1/
// original
var arr = [{
key: '11',
value: '1100',
$$hashKey: '00X'
},
{
key: '22',
value: '2200',
$$hashKey: '018'
}
];
// My solution
var obj = {};
for (let i = 0; i < arr.length; i++) {
obj[arr[i].key] = arr[i].value;
}
console.log(obj)
You can use the mapKeys lodash function for that. Just one line of code!
Please refer to this complete code sample (copy paste this into repl.it or similar):
import _ from 'lodash';
// or commonjs:
// const _ = require('lodash');
let a = [{ id: 23, title: 'meat' }, { id: 45, title: 'fish' }, { id: 71, title: 'fruit' }]
let b = _.mapKeys(a, 'id');
console.log(b);
// b:
// { '23': { id: 23, title: 'meat' },
// '45': { id: 45, title: 'fish' },
// '71': { id: 71, title: 'fruit' } }
I have an array like so with a single object inside:
FirstArray = [{
"category": "None",
"ARFE": 553.5,
"BV": 900,
"RF rfeer": 0,
.....
}]
I want to convert it so that every key-value pair (where the value is a number) in the object is in its own object like the following:
NewArray = [{
name: "ARFE",
value: 553.05
}, {
name: "BV",
value: 900
}, {
name: "RF rfeer",
value: 0
}, .....]
Here, each key was assigned a new key called name, and the value for the original key was assigned a new key called value. Those pairs are then put into their own object inside the array.
Note that "category": "None" is not its own object in the array since "None" is non-numerical.
It's also important to note that there could be many key-value pairs, so it's not just limited to the items above (e.g., "ARFE": 553.5, etc.)
What I have so far:
I know you can separate a single object into multiple objects:
NewArray = Object.entries(FirstArray).reduce((prev, [og, nw]) => {
let [name, value] = og.match(/\D+|\d+$/g)
prev[value] = { ...(prev[value] || {}), [name]: nw }
return prev;
}, {})
I also know how that you can create a new object with new keys like so:
NewArray = Object.assign(
...Object.entries(FirstArray).map(([key, value]) => ({ [key]: name }))
);
However, I'm having trouble putting everything together. How would I be able to achieve NewArray from FirstArray?
You were pretty close. All you needed to do is specify the name:
const data = {
"category": "None",
"ARFE": 553.5,
"BV": 900,
"RF rfeer": 0
};
const result = Object
.entries(data)
.filter(([_, value]) => typeof value === 'number')
.map(([key, value]) => ({ name: key, value }));
console.log(result);
Also, if you don't want { "name": "category", "value": "None" } to be included in the result, you can just filter it:
const result = Object
.entries(data)
.filter(([ key ]) => key !== 'category')
.map(([key, value]) => ({ name: key, value }));
Object.entries on array has no sense at all, use it on the object
const FirstArray = [{
"category": "None",
"ARFE": 553.5,
"BV": 900,
"RF rfeer": 0,
}]
const newObject = Object.entries(FirstArray[0]).reduce((array, [key, value]) => {
return [...array, {
name: key,
value
}]
}, [])
console.log(newObject)
reduce is not the right way to go. Simply use map:
Object.entries(FirstArray[0])
.filter(x => !isNaN(x[1])) // filter out non-numeric values
.map(([name, value]) => ({name, value}))
I'm trying to add into an array. I don't know how to traverse and add objects correctly.
I have data array:
const data = [
{
1: "Apple",
2: "Xiaomi"
}
];
const list = [];
data.forEach(function(key, value) {
console.log("key", key);
})
console.log(list)
I want this effect to be as follows:
list: [{
{
value: 1,
title: 'Apple'
},
{
value: 2,
title: 'Xiaomi'
}
}]
Your expected output is invalid. You can first retrieve all the values from the object with Object.values(). Then use Array.prototype.map() to form the array in the structure you want.
Try the following way:
const data = [
{
1: "Apple",
2: "Xiaomi"
}
];
const list = Object.values(data[0]).map((el,i) => ({value: i+1, title: el})) ;
console.log(list);
You can use the existing key of the object with Object.entries() like the following way:
const data = [
{
1: "Apple",
2: "Xiaomi"
}
];
const list = Object.entries(data[0]).map(item => ({value: item[0], title: item[1]}));
console.log(list);
I'll go ahead and make the assumption that data is an object of key/value pairs and you want to transform it to an array of objects.
// Assuming you have an object with key/value pairs.
const data = {
1: "Apple",
2: "Xiaomi"
};
// Convert the data object into an array by iterating over data's keys.
const list = Object.keys(data).map((key) => {
return {
value: key,
title: data[key]
}
});
console.log(list)
Output:
[
{
value: '1',
title: 'Apple'
},
{
value: '2',
title: 'Xiaomi'
}
]
If you actually need value to be numbers instead of strings, you can do it this way:
const list = Object.keys(data).map((key) => {
return {
value: Number(key),
title: data[key]
}
});
And if you are OK with using a more modern version of JavaScript (ECMAScript 2017) this works nicely:
const data = {
1: "Apple",
2: "Xiaomi"
};
// Using Object.entries gives you the key and value together.
const list = Object.entries(data).map(([value, title]) => {
return { value, title }
});
You could do something like this:
const data = ['Apple', 'Xiaomi'];
const result = data.map((item, index) => ({value: index, title: item}));
console.log(result);
If the idea is to turn key names into values and those are not necessarily autoincremented numbers you might want to look at Object.entries():
const data = {1: "Apple", 2: "Xiaomi"};
const res = Object.entries(data).map(entry => ({value: entry[0], title: entry[1]}));
console.log(res);
I have an object like
const obj = {
apple:'red',
banana:'yellow'
}
I need to return an array with properties/values using ramda.
Example:
[
{
name: 'apple',
value:'red'
},
{
name: 'banana',
value:'yellow'
},
]
A ramda solution:
R.pipe(
R.toPairs,
R.map(R.zipObj(['name', 'value']))
)(obj)
You can achieve that without any 3rd party lib, with Object.entries, that returns an array with an array that contains key & value, map over it to convert it to an object.
const obj = {
apple: 'red',
banana: 'yellow'
};
const result = Object.entries(obj)
.map(([name, value]) => ({
name,
value
}));
console.log(result);
How can I transform a big object to array with 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...}]
You can do
var arr = _.values(obj);
For documentation see here.
A modern native solution if anyone is interested:
const arr = Object.keys(obj).map(key => ({ key, value: obj[key] }));
or (not IE):
const arr = Object.entries(obj).map(([key, value]) => ({ key, value }));
_.toArray(obj);
Outputs as:
[
{
"name": "Ivan",
"id": 12,
"friends": [
2,
44,
12
],
"works": {
"books": [],
"films": []
}
},
{
"name": "John",
"id": 22,
"friends": [
5,
31,
55
],
"works": {
"books": [],
"films": []
}
}
]"
For me, this worked:
_.map(_.toPairs(data), d => _.fromPairs([d]));
It turns
{"a":"b", "c":"d", "e":"f"}
into
[{"a":"b"}, {"c":"d"}, {"e":"f"}]
There are quite a few ways to get the result you are after. Lets break them in categories:
ES6 Values only:
Main method for this is Object.values. But using Object.keys and Array.map you could as well get to the expected result:
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 Key & Value:
Using map and ES6 dynamic/computed properties and destructuring you can retain the key and return an object from the 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 only:
The method designed for this is _.values however there are "shortcuts" like _.map and the utility method _.toArray which would also return an array containing only the values from the object. You could also _.map though the _.keys and get the values from the object by using the obj[key] notation.
Note: _.map when passed an object would use its baseMap handler which is basically forEach on the object properties.
_.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.
If you want the key (id in this case) to be a preserved as a property of each array item you can do
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
Transforming object to array with plain JavaScript's(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);
If you also want to keep the keys use Object.entries and Array#map like this:
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);
Object to Array
Of all the answers I think this one is the best:
let arr = Object.entries(obj).map(([key, val]) => ({ key, ...val }))
that transforms:
{
a: { p: 1, q: 2},
b: { p: 3, q: 4}
}
to:
[
{ key: 'a', p: 1, q: 2 },
{ key: 'b', p: 3, q: 4 }
]
Array to Object
To transform back:
let obj = arr.reduce((obj, { key, ...val }) => { obj[key] = { ...val }; return obj; }, {})
To transform back keeping the key in the value:
let obj = arr.reduce((obj, { key, ...val }) => { obj[key] = { key, ...val }; return obj; }, {})
Will give:
{
a: { key: 'a', p: 1, q: 2 },
b: { key: 'b', p: 3, q: 4 }
}
For the last example you can also use lodash _.keyBy(arr, 'key') or _.keyBy(arr, i => i.key).
2017 update: Object.values, lodash values and toArray do it. And to preserve keys map and spread operator play nice:
// 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>
var arr = _.map(obj)
You can use _.map function (of both lodash and underscore) with object as well, it will internally handle that case, iterate over each value and key with your iteratee, and finally return an array. Infact, you can use it without any iteratee (just _.map(obj)) if you just want a array of values. The good part is that, if you need any transformation in between, you can do it in one go.
Example:
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.
If you want some custom mapping (like original Array.prototype.map) of Object into an Array, you can just use _.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' }, ... ];
See lodash doc of _.forEach https://lodash.com/docs/#forEach