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 of object, something like this:
array = [
{
'propertyName1': 'name1',
'propertyValue1': 'value1',
'propertyName2': 'name2',
'propertyValue2': 'value2',
'propertyName3': 'name3',
'propertyValue3': 'value3',
'propertyName4': 'name4',
'propertyValue4': 'value4',
},
{
'propertyName1': 'name10',
'propertyValue1': 'value10',
'propertyName2': 'name22',
'propertyValue2': 'value22',
'propertyName3': 'name33',
'propertyValue3': 'value33',
'propertyName4': null,
'propertyValue4': null,
}
]
I want to get the first value as a key and the second value as a value in a new object, something like this result:
{
name1: "value1"
name10: "value10"
name2: "value2"
name22: "value22"
name3: "value3"
name33: "value33"
name4: "value4"
null: null
}
but I don't want to show the property with the value null, so I tried:
ngOnInit() {
let obj = {};
this.array.forEach((element: any) => {
obj = {
...obj,
[element.propertyName1]: element.propertyValue1,
[element.propertyName2]: element.propertyValue2,
[element.propertyName3]: element.propertyValue3,
[element.propertyName4]: element.propertyValue4}
}
);
console.log(obj);
}
See the code here:
Stackblitz
Just delete the null entry after
this.array.forEach((element: any) => {
obj = {
...obj,
[element.propertyName1]: element.propertyValue1,
[element.propertyName2]: element.propertyValue2,
[element.propertyName3]: element.propertyValue3,
[element.propertyName4]: element.propertyValue4,
};
});
delete obj['null'];
https://stackblitz.com/edit/angular-ivy-gaqes8?file=src/app/app.component.ts
You can spread all the values in a single array and check if the property is null while looping over:
ngOnInit() {
const valuesArray = [ //Array containing all the values
...Object.values(this.array[0]),
...Object.values(this.array[1]),
];
let obj = {};
for (let i = 0; i < valuesArray.length; i = i + 2) {
if (valuesArray[i + 1] !== null) {
obj[valuesArray[i]] = valuesArray[i + 1]; //Only copy when it is not null
}
}
console.log(obj);
}
If your first array also might contain null values and you want to exclude them you can use this if condition instead of the one above:
if (valuesArray[i + 1] !== null && valuesArray[i] !== null )
const data = [{"propertyName1":"name1","propertyValue1":"value1","propertyName2":"name2","propertyValue2":"value2","propertyName3":"name3","propertyValue3":"value3","propertyName4":"name4","propertyValue4":"value4"},{"propertyName1":"name10","propertyValue1":"value10","propertyName2":"name22","propertyValue2":"value22","propertyName3":"name33","propertyValue3":"value33","propertyName4":null,"propertyValue4":null}]
let r = {}
// get maximum number of keys that may need to be iterated over
let n = data.map(o=>Object.keys(o).length).reduce((a,c)=>Math.max(a,c))
for(let i=1; i<=n; i++) {
data.forEach(o=> {
let x = o[`propertyName${i}`]
let y = o[`propertyValue${i}`]
if (x && y) r[x] = y
})
}
console.log(r)
Just looking for the cleanest way to turn the following array into the following object format. Thanks a lot
const item = [
{ address: '123 fake street' },
{ loan: 'no' },
{ property: 'no' }
]
const obj = {
address: '123 fake street',
loan: 'no',
property: 'no'
}
You can use Object.assign() and spread syntax to convert the array of objects into a single object.
const item = [
{ address: '123 fake street' },
{ loan: 'no' },
{ property: 'no' }
]
const obj = Object.assign({}, ...item);
console.log(obj);
Reduce and spread syntax would be one clean way to convert the array to an object.
const item = [
{ address: '123 fake street' },
{ loan: 'no' },
{ property: 'no' }
]
let obj = item.reduce((pre, cur)=>{
return {...pre, ...cur};
}, {});
// Result: obj={address: '123 fake street', loan: 'no', property: 'no'}
Just use a simple for...of loop to iterate over the array, and Object.entries to extract the key/value. Then just update an empty object with that information
const item = [
{ address: '123 fake street' },
{ loan: 'no' },
{ property: 'no' }
];
const obj = {};
for (const el of item) {
const [[key, value]] = Object.entries(el);
obj[key] = value;
}
console.log(obj);
Additional documentation
Destructuring assignment
const arr = [{key:"address", value:"123 fake street"},{key:"loan", value:"no"},{key:"property", value:"no"}];
const object = arr.reduce(
(obj, item) => Object.assign(obj, { [item.key]: item.value }), {});
console.log(object)
One more solution which is 99% faster (jsperf tested)
const object = arr.reduce((obj, item) => (obj[item.key] = item.value, obj) ,{});
and More simplest solution
// original
const arr = [
{key:"address", value:"123 fake street"},
{key:"loan", value:"no"},
{key:"property", value:"no"}
];
//convert
const result = {};
for (var i = 0; i < arr.length; i++) {
result[arr[i].key] = arr[i].value;
}
console.log(result);
I have an object that is structured like this:
{
question: 'something',
node: [
{ question: 'something', node: [{ question: 'something' }] },
{ question: 'something' }
]
}
What I want to do is return a certain property from the whole object, for example, return all the question properties like this:
[{question: 'somthing'}, ...]
Below is a recursive function returnProperty, which takes the object, property name and an array as argument. It populates the array with desired property items (questionlist in below code).
function returnProperty(obj, propName, propertList=[]){
if(obj[propName]){
let propObj = {};
propObj[propName]=obj[propName];
propertList.push(propObj);
}
if(obj.node && obj.node.length){
for(let nodeObj of obj.node){
returnProperty(nodeObj, propName, propertList);
}
}
}
let obj = {
question: 'something',
node: [
{ question: 'something', node: [{ question: 'something' }] },
{ question: 'something' }
]
};
let questionList = [];
returnProperty(obj, 'question', questionList);
console.log(questionList);
Here is a solution that works with ANY key values. You can have
{
question: 'yx',
x: [{question: 'x'}]
}
and it will extract successfully.
const x = {
question: 'something',
node: [
{ question: 'something', node: [{ question: 'fun' }] },
{ question: 'something' }
]
}
const keyToCheck = 'question'
const process = (obj) => {
let output = []
for (const [key, value] of Object.entries(obj)) {
if (key.toString() === keyToCheck) {
output.push({[keyToCheck]: value})
continue;
}
if (Array.isArray(value)) {
for (const arrObj of value) {
output = output.concat(process(arrObj))
}
}
}
return output
}
console.log(process(x))
Define a recursive function getSomething(objOrArray) and a storage array results. See if an object or an array is passed in. Apply either Object.keys(objOrArray) or objOrArray.forEach() to step into the object or array,
if this is an array or a key points to an object or array, call itself getSomething
otherwise if the key is "question", push the key-value pair into results.
I don't know how to write the title properly, pardon me on that.
Basically I have a list of array of object that's coming from a place, I need to map them together. How how with my code below I can't make it.
const person = [
{name:'hello',id:1},
{name:'javascript',id:2},
{name:'world',id:3}
];
const selected = [2,3];
const normalized = person.map((obj,i) => obj.id === selected[i] ? Object.assign({}, obj, {checked:true}) : obj);
console.log(normalized)
https://jsfiddle.net/q9g0kazx/1/
I need to add an extra property base on the selected array. Why above code doesn't work?
If I understand you correctly, just iterate through the array using forEach and add the property if needed.
const person = [
{name: 'hello', id: 1},
{name: 'javascript',id: 2},
{name: 'world',id: 3}
];
const selected = [2,3];
person.forEach(p => {
if (selected.includes(p.id)) {
p.checked = true;
}
});
console.log(person);
Or you can use map like this:
const person = [
{name: 'hello', id: 1},
{name: 'javascript',id: 2},
{name: 'world',id: 3}
];
const selected = [2,3];
person.map(p => {
if (selected.includes(p.id)) {
p.checked = true;
}
return p;
});
console.log(person);
Notice that you have to return the object (person in our case)
You can do this:
Check if the the id in the array is present in the selected array by:
selected.includes(obj.id)
So, includes returns true if the obj.id was present in the selected array. If present(yes) then your Object.assignpart of code executes.
The reason your code was not working was because your person array and selected array don't have same number of elements(count) and perhaps not in the order as well.
So person[0] id which is 1 doesn't match with selected[0] id which 2 and so on.
const person = [{
name: 'hello',
id: 1
},
{
name: 'javascript',
id: 2
},
{
name: 'world',
id: 3
}
];
const selected = [2, 3];
const normalized = person.map((obj, i) => selected.includes(obj.id) ? Object.assign({}, obj, {
checked: true
}) : obj);
console.log(normalized);