I have this data:
const langs = {
en: ['One', 'description'],
pl: ['Jeden', 'opis'],
};
And I'm trying to parse it into this format:
const formattedData = {
name: {
en: "One",
pl: "Jeden",
},
description: {
en: "description",
pl: "opis",
}
};
I tried to do something like this:
const langs = {
en: ['One', 'description'],
pl: ['Jeden', 'opis'],
};
const val = Object.keys(langs).map(item => ({
[item]: langs[item][0]
}))
console.log(val);
I'd use Object.entries to get key, value pair and then add an object which has name and description keys already defined
const langs = {
en: ['One', 'description'],
pl: ['Jeden', 'opis'],
};
let val = {name:{}, description:{}}
Object.entries(langs).forEach(([key,v])=>{
val.name[key]=v[0]
val.description[key]=v[1]
})
console.log(val)
Here's how you could do it with Object.keys, as asked. You may need to create the target object structure in advance (or at least it's more readable to do so).
const langs = {
en: ['One', 'description'],
pl: ['Jeden', 'opis'],
};
let newObj = {
name: {},
description: {}
};
Object.keys(langs).forEach(item => {
newObj.name[item] = langs[item][0];
newObj.description[item] = langs[item][1];
});
console.log(newObj);
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' } }
as seen in my title I am facing a problem that needs a solution. I am trying to filter my object, but not only based on keys. But also based on the value of the allowed keys.
This is what I got so far:
const handleSearch = (searchValue) => {
if(searchValue !== '') {
const allowed = ['name', 'title'];
let list = props.search.list;
const filtered = Object.keys(list)
.filter((key) => allowed.includes(key))
.reduce((obj, key) => {
obj[key] = list[key];
return obj;
}, {});
const filteredArray = Object.entries(filtered)
props.search.onChange(filteredArray)
} else {
props.search.onChange(props.search.list)
}
}
Structure of the list object:
0: {name: "John', title: 'Owner'}
1: {name: "Jane", title: 'Admin'}
Wanted results:
Filtered array that shows the keys filtered aswell as the search value.
And I don't know where I should integrate the filtering by the values aswell. This has been giving me a headache for the past few hours. And hope someone here is experienced with these kinds of issues/logic.
Thanks for reading.
Kind regards.
const handleSearch = (searchValue) => {
if (searchValue !== '') {
const allowed = ['name', 'title'];
const list = props.search.list;
const filtered = list
.filter(obj =>
Object.keys(obj)
.some(k => allowed.includes(k))
)
.filter(obj =>
Object.values(obj)
.map(v => v.toLocaleLowerCase())
.some(v => v.includes(searchValue.toLowerCase()))
)
props.search.onChange(filtered)
} else {
props.search.onChange(props.search.list)
}
}
Example
Let's assume props as:
const props = {
search: {
list: [
{ name: "John", title: 'Owner' },
{ name: "Jane", title: 'Admin' },
{ name: "Reza", title: 'Owner' }
],
onChange: x => console.log(x)
},
}
handleSearch("own")
// [ { name: 'John', title: 'Owner' }, { name: 'Reza', title: 'Owner' } ]
handleSearch("jane")
// [ { name: 'Jane', title: 'Admin' } ]
handleSearch("something")
// []
I have an array object with following data:
const arr = [
{
key: 'mykey1597855209',
integrity: 'sha512-T9JWj=='
},
{
key: 'mykey159785520915978552101597855212',
integrity: 'sha512-T9JWj=='
},
{
key: 'mykey15978552091597855210',
integrity: 'sha512-lcddfd=='
},
{
key: 'otherkey15978552091597855210',
integrity: 'sha512-abcdfd=='
}];
I want to create key value pair from the the arr[] object such that integrity becomes key and the key becomes value
Desired Output is something like below:
{
"sha512-T9JWj==": [
"mykey1597855209",
"mykey159785520915978552101597855212"
],
"sha512-lcddfd==": [
"mykey15978552091597855210"
],
"sha512-abcdfd==": [
"otherkey15978552091597855210"
]
}
I have written following code:
const arr = [{
key: 'mykey1597855209',
integrity: 'sha512-T9JWj=='
},
{
key: 'mykey159785520915978552101597855212',
integrity: 'sha512-T9JWj=='
},
{
key: 'mykey15978552091597855210',
integrity: 'sha512-lcddfd=='
},
{
key: 'otherkey15978552091597855210',
integrity: 'sha512-abcdfd=='
}
];
const result = Object.assign(...arr.map(a => ({
[a.integrity]: a.key
})));
console.log(result)
You can use Object.fromEntries:
const arr = [{key: 'mykey1597855209',integrity: 'sha512-T9JWj=='},{key: 'mykey159785520915978552101597855212',integrity: 'sha512-T9JWj=='},{key: 'mykey15978552091597855210',integrity: 'sha512-lcddfd=='},{key: 'otherkey15978552091597855210',integrity: 'sha512-abcdfd=='}];
let map = Object.fromEntries(arr.map(({_, integrity }) => [integrity, []]));
arr.forEach(({key, integrity}) => map[integrity].push(key));
console.log(map);
Or reduce:
const arr = [{key: 'mykey1597855209',integrity: 'sha512-T9JWj=='},{key: 'mykey159785520915978552101597855212',integrity: 'sha512-T9JWj=='},{key: 'mykey15978552091597855210',integrity: 'sha512-lcddfd=='},{key: 'otherkey15978552091597855210',integrity: 'sha512-abcdfd=='}];
let map = arr.reduce((acc, { key, integrity }) => {
acc[integrity] = acc[integrity] || [];
acc[integrity].push(key);
return acc;
}, {});
console.log(map);
You can transform it like this:
let map = {};
arr.forEach({ key, integrity } => map[integrity] = key);
arr.reduce((acc, curr) => {
acc[curr.integrity] = (acc[curr.integrity]) ?
[ ...acc[curr.integrity], curr.key ] :
[ curr.key ]
return acc;
}, {})
I have a JS array (shown 4 examples actual has 66 )
[["A","Example1"],["A","Example2"],["B","Example3"],["B","Example4"]]
that I am trying to get into an object for a multi select drop down menu:
var opt = [{
label: 'A', children:[
{"label":"Example1","value":"Example1","selected":"TRUE"},
{"label":"Example2","value":"Example2","selected":"TRUE"}
]
},
{
label: 'B', children:[
{"label":"Example3","value":"Example3","selected":"TRUE"},
{"label":"Example4","value":"Example4","selected":"TRUE"}
]
}
]
Is there a easy way to do this ?
Updated:
Using reduce() and filter() to get expected results.
const result = [['A', 'Example1'], ['A', 'Example2'], ['B', 'Example3'], ['B', 'Example4']].reduce((acc, cur) => {
const objFromAccumulator = acc.filter((row) => row.label === cur[0]);
const newChild = {label: cur[1], value: cur[1], selected: 'TRUE'};
if (objFromAccumulator.length) {
objFromAccumulator[0].children.push(newChild);
} else {
acc.push({label: cur[0], children: [newChild]});
}
return acc;
}, []);
console.log(result);
Something like this should work:
const raw = [["A","Example1"],["A","Example2"],["B","Example3"],["B","Example4"]];
const seen = new Map();
const processed = raw.reduce((arr, [key, label]) => {
if (!seen.has(key)) {
const item = {
label: key,
children: []
};
seen.set(key, item);
arr.push(item);
}
seen.get(key).children.push({
label,
value: label,
selected: "TRUE"
})
return arr;
}, []);
console.log(processed);
Here's a rather efficient and concise take on the problem using an object as a map:
const data = [["A","Example1"],["A","Example2"],["B","Example3"],["B","Example4"]];
const opt = data.reduce((results,[key,val]) => {
if(!results[0][key]) //first element of results is lookup map of other elements
results.push(results[0][key] = { label: key, children: [] });
results[0][key].children.push({ label: val, value: val, selected:"TRUE" });
return results;
}, [{}]).slice(1); //slice off map as it's no longer needed
console.log(opt);
I have a bidimensional array like this:
const bArray =
[ [ 'Hello World',
'Hi everybody',
'How are you?'
],
[ { text: 'Hola Mundo',
from: [Object],
raw: '' },
{ text: 'Hola a todos',
from: [Object],
raw: '' },
{ text: 'Cómo estás?',
from: [Object],
raw: '' },
]
]
And I need to get as a result, only one array that should look like this:
[
{ en: 'Hello World',
es: 'Hola Mundo' },
{ en: 'Hi everybody',
es: 'Hola a todos' },
{ en: 'How are you?',
es: 'Cómo estás?' },
]
This is how I do it:
let val1 = bArray[0].map(tuple => tuple);
let val2 = bArray[1].map(tuple => tuple);
let result = val1.reduce((arr, v, i) => arr.concat({"en" : v, "es" : val2[i].text}), []);
And now in the result variable, I have only one array with the result showed before.
My question?
Is there any improved way in which I can get the same result but with fewer lines of code? I mean, something like a combination of map with reduce, filter or concat without creating two separte arrays like val1 and val2.
If you simply do:
bArray[0].reduce((arr, v, i) => arr.concat({"en" : v, "es" : bArray[1][i].text}), []);
You can get the same thing in just one line.
Explanation:
let val1 = bArray[0].map(tuple => tuple);
let val2 = bArray[1].map(tuple => tuple);
This is doing nothing but get the elements in the array. It's exactly the same thing as:
let val1 = bArray[0];
let val2 = bArray[1];
So I just direct accessed the bArray indexes in your original line.
I am assuming there will be only two arrays inside outer array. You simply need to loop on first array and pick the text from from other array at same index and merge them into one object.
const bArray =
[ [ 'Hello World',
'Hi everybody',
'How are you?'
],
[ { text: 'Hola Mundo',
from: [],
raw: '' },
{ text: 'Hola a todos',
from: [],
raw: '' },
{ text: 'Cómo estás?',
from: [],
raw: '' },
]
];
let result = bArray[0].map((item, index) => {
return {
en: item,
es: bArray[1][index].text
};
});
console.log(result);
Yet another variation using Array.prototype.forEach() method
let result = [];
bArray[0].forEach((item, index) => {
result.push({
en: item,
es: bArray[1][index].text
});
});
console.log(result);