I have:
var keys = [ "height", "width" ];
var values = [ "12px", "24px" ];
And I'd like to convert it into this object:
{ height: "12px", width: "24px" }
In Python, there's the simple idiom dict(zip(keys,values)). Is there something similar in jQuery or plain JavaScript, or do I have to do this the long way?
The simplest ES6 one-liner solution using Array reduce:
const keys = ['height', 'width'];
const values = ['12px', '24px'];
const merged = keys.reduce((obj, key, index) => ({ ...obj, [key]: values[index] }), {});
console.log(merged);
Simple JS function would be:
function toObject(names, values) {
var result = {};
for (var i = 0; i < names.length; i++)
result[names[i]] = values[i];
return result;
}
Of course you could also actually implement functions like zip, etc as JS supports higher order types which make these functional-language-isms easy :D
use lodash.
_.zipObject
Example
_.zipObject(['a', 'b'], [1, 2]);
// ➜ { 'a': 1, 'b': 2 }
As an alternate solution, not already mentioned I think :
var result = {};
keys.forEach((key, idx) => result[key] = values[idx]);
You can combine two arrays with map method, then convert it with Object.fromEntries.
var keys = ["height", "width"];
var values = ["12px", "24px"];
var array = keys.map((el, i) => {
return [keys[i], values[i]];
});
// → [["height", "12px"], ["width", "24px"]]
var output = Object.fromEntries(array);
// → {height: "12px", width: "24px"}
console.log(output);
A functional approach with immutability in mind:
const zipObj = xs => ys => xs.reduce( (obj, x, i) => ({ ...obj, [x]: ys[i] }), {})
const arr1 = ['a', 'b', 'c', 'd']
const arr2 = ['e', 'f', 'g', 'h']
const obj = zipObj (arr1) (arr2)
console.log (obj)
You could use a reduce() function to map the key-value pairs to an object.
/**
* Apply to an existing or new object, parallel arrays of key-value pairs.
*
* #param {string[]} keys - List of keys corresponding to their accociated values.
* #param {object[]} vals - List of values corresponding to their accociated keys.
* #param {object} [ref={}] - Optional reference to an existing object to apply to.
*
* #returns {object} - The modified or new object with the new key-value pairs applied.
*/
function toObject(keys, vals, ref) {
return keys.length === vals.length ? keys.reduce(function(obj, key, index) {
obj[key] = vals[index];
return obj;
}, ref || {}) : null;
}
var keys = [ "height" , "width" ];
var values = [ "12px" , "24px" ];
document.body.innerHTML = '<pre>' + JSON.stringify(toObject(keys, values), null, 2) + '</pre>';
Here's an example with all consts (non-modifying) and no libraries.
const keys = ["Adam", "Betty", "Charles"];
const values = [50, 1, 90];
const obj = keys.reduce((acc, key, i) => {
acc[key] = values[i];
return acc;
}, {});
console.log(obj);
Alternatively, if you'd consider libraries you could use lodash zipobject which does just what you asked.
Now we have Object.fromEntries we can do something like that:
const keys = [ "height", "width" ];
const values = [ "12px", "24px" ];
const myObject = Object.fromEntries(
values.map((value, index) => [keys[index], value])
);
console.log(myObject);
You could transpose the arrays and get the object with the entries.
const
transpose = (r, a) => a.map((v, i) => [...(r[i] || []), v]),
keys = [ "height", "width" ],
values = [ "12px", "24px" ],
result = Object.fromEntries([keys, values].reduce(transpose, []));
console.log(result);
function combineObject( keys, values)
{
var obj = {};
if ( keys.length != values.length)
return null;
for (var index in keys)
obj[keys[index]] = values[index];
return obj;
};
var your_obj = combine( your_keys, your_values);
Here's one which will transform nested arrays into an array of multiple key-value objects.
var keys = [
['#000000', '#FFFFFF'],
['#FFFF00', '#00FF00', '#00FFFF', '#0000FF'],
];
var values = [
['Black', 'White'],
['Yellow', 'Green', 'Cyan', 'Blue'],
];
const zipObj = xs => ys => xs.reduce( (obj, x, i) => ({ ...obj, [x]: ys[i] }), {})
var array = keys.map((el, i) => zipObj (keys[i]) (values[i]));
console.log(array);
Output is
[
{
"#000000": "Black",
"#FFFFFF": "White"
},
{
"#FFFF00": "Yellow",
"#00FF00": "Green",
"#00FFFF": "Cyan",
"#0000FF": "Blue"
}
]
Providing a solution with a for...of loop.
var keys = ["height", "width"];
var values = ["12px", "24px"];
const result = {};
for (let [index, key] of keys.entries())
result[key] = values[index];
console.log(result);
You can also use a library like ramda which has zipObj function.
Example:
const keys = ["height", "width"];
const values = ["12px", "24px"];
const result = R.zipObj(keys, values);
console.log(result);
In the jQuery-Utils project, the ArrayUtils module has a zip function implemented.
//...
zip: function(object, object2, iterator) {
var output = [];
var iterator = iterator || dummy;
$.each(object, function(idx, i){
if (object2[idx]) { output.push([i, object2[idx]]); }
});
return output;
}
//...
Related
var c = {
'aa-bb': [{ a: 1, v: 2}],
'cc-xz': [{ c: 2}]
}
console.log(Object.keys(c))
I need to create an object, whose keys (the name) must be from Object.keys.
For each key name an object of type array must be defined as below.
Can you give me a hand?
result:
const res = {
'aa-bb': Array(number).fill(0),
'cc-xz': Array(number).fill(0)
};
var c = {
'aa-bb': [{
a: 1,
v: 2
}],
'cc-xz': [{
c: 2
}]
}
const keys = Object.keys(c);
let res = {},
number = 5;
keys.forEach(key => res[key] = Array(number).fill(0));
console.log(res);
Map the keys, and create pairs of [key, array], and convert back to an object using Object.fromEntries():
const fn = (obj, arrLengh) =>
Object.fromEntries(
Object.keys(obj)
.map(key => [key, Array(arrLengh).fill(0)])
);
const c = {"aa-bb":[{"a":1,"v":2}],"cc-xz":[{"c":2}]};
const result = fn(c, 5);
console.log(result);
I'm trying to retrieve all unique values from an array inside and object, inside an array
var items = [
{
colors:['white', 'black'],
fruits:['apple, banana']
},
{
colors:['yellow', 'black'],
fruits:['mango, blueberry'],
},
...
]
const property = 'colors'
const values = this.distinct(this.items.map(item => item[property].map(elem => elem))
I want the values to return an array with each value of colors so, like this:
['black','white','yellow']
But it's not working, and I don't understand why
flatMap the array of objects to extract each colors sub-array, pass into the Set constructor to de-duplicate, and turn the Set back into an array:
var items = [{
colors:['white', 'black'],
fruits:['apple, banana']
},{
colors:['yellow', 'black'],
fruits:['mango, blueberry'],
}];
const colorsSet = new Set(
items.flatMap(item => item.colors)
);
const uniques = [...colorsSet];
console.log(uniques);
reduce can be used to iterate through array and assign a color as key of accumulator object:
const result = items.reduce((a, {colors})=> {
colors.forEach(cl => a[cl] = 1);
return a;
}, {})
console.log(Object.keys(result));
Or one line way:
Object.keys(items.reduce((a, {colors})=> (colors.forEach(cl => a[cl] = 1) , a), {}));
Read more about reduce method
An example:
let items = [
{
colors: ['white', 'black'],
fruits: ['apple, banana']
},
{
colors: ['yellow', 'black'],
fruits: ['mango, blueberry'],
}
]
const result = items.reduce((a, {colors})=> {
colors.forEach(cl => a[cl] = 1);
return a;
},{})
console.log(Object.keys(result));
const oneLine = Object.keys(items.reduce((a, {colors})=>
(colors.forEach(cl => a[cl] = 1) , a), {}));
console.log(oneLine);
At the entrance I have such an array with objects.
Function that converts an incoming array of objects into an object.
Using the function, I need to bring it to this form.
var array = [
{ k1:v1 },
{ k2:v2 },
{ k3:v3 }
];
function arrayToObject(array) { return object }
var object = {
v1: k1,
v2: k2,
v3: k3,
}
You could taske Object.assign and spread the reversed objects.
var array = [ { k1: 'v1' }, { k2: 'v2' }, { k3: 'v3' }],
object = Object.assign(...array.map(o => Object
.entries(o)
.reduce((r, [k, v]) => Object.assign(r, { [v] : k }), {})
));
console.log(object);
Use forEach loop
var array = [
{ k1:'v1' },
{ k2:'v2' },
{ k3:'v3' }
]
function a()
{
var obj={};
array.forEach((e)=>obj[e[Object.keys(e)[0]]]=Object.keys(e)[0])
console.log(obj)
}
a();
You can use Object.entries() and .reduce() methods to get the desired output:
const array = [
{ k1:'v1' },
{ k2:'v2' },
{ k3:'v3' }
];
const obj = Object.entries(
array.reduce((r, c) => Object.assign(r, c), {})
).reduce((r, [k, v]) => (r[v] = k, r), {});
console.log(obj);
Array.reduce and use Object.keys over each array element.
var array = [
{ k1: 'v1' },
{ k2: 'v2' },
{ k3: 'v3' }
]
var obj = array.reduce((obj, item) => {
Object.keys(item).forEach(key => obj[item[key]] = key)
return obj
}, {})
console.log(obj)
And another one:
const result = {};
for(const [[key, value]] of array.map(Object.entries))
result[value] = key;
I am not sure why the other answers go through hoops to make this as clever as possible.
I find this more readable. I am not using reduce because I find the word misleading. A simple forEach makes more sense to me
const array = [
{ k1:'v1' },
{ k2:'v2' },
{ k3:'v3' }
];
let newObj={};
array.forEach((obj) => {
let key = Object.keys(obj)[0];
newObj[obj[key]]=key;
})
console.log(newObj)
your answer..
var array = [
{ k1: v1 },
{ k2: v2 },
{ k3: v3 }
];
function arrayToObject(array) {
obj = {};
for (i = 0; i < array.length; i++) {
o = array[i];
key = Object.keys(o)[0];
obj.key = o.key;
}
return obj;
}
console.log(arrayToObject(array))
Array of dictionaries should be converted simpler form.
data = [{A:1},{B:2},{C:3}]
data = {A: 1, B: 2}
data = ["0":{ A : 1, B : 2 , C : 3}]
Both are completely different datasets. I'm trying to map it also like below format.
The above should become like
data = [
{
name: "A",
y: 1
},
{
name: "B",
y: 2
},
{
name: "C",
y: 3
}
];
I tried this following approach but it's wrong
name = {}
data.forEach(function(k,x){
return name['name'] = k , name["y"] = x
})
Please suggest me a better approach.
map each object's entries to extract the key and the value, and return an object with name and y keys:
const data = [{A:1},{B:2},{C:3}]
const output = data.map(item => {
const [name, y] = Object.entries(item)[0];
return { name, y };
});
console.log(output);
If the keys (A, B, etc) are guaranteed to be unique throughout the array, then everything becomes simpler.
const data = [{A:1},{B:2},{C:3}];
const merged = Object.assign({}, ...data);
const newData = Object.entries(merged)
.map(([name, y]) => ({ name, y }));
console.log(newData);
However, if the keys aren't guaranteed unique, then refer to CertainPerformance's answer.
you can implement like this
var data = [{A:1},{B:2},{C:3}];
var reformattedArra = data.map(obj => {
let val = {};
val.name = Object.keys(obj)[0];
val.y = obj[Object.keys(obj)[0]];
return val;
})
console.log(JSON.stringify(reformattedArra));
I would say, use Object.keys() which is widly supported
let data = [{A:1},{B:2},{C:3}];
data = Object.assign({}, ...data);
data = Object.keys(data).map(key => ({ name: key, y: data[key] }));
console.log(data);
You yould could chekc the data format and if it is not an array, build one and reduce the array by taking the objetcs and create for each key/value a new object for the result set.
function simple(data) {
return (Array.isArray(data) ? data : [data]).reduce((r, o) => [...r, ...Object.entries(o).map(([name, y]) => ({ name, y }))], []);
}
console.log(simple([{ A: 1 }, { B: 2 }, { C: 3, D: 4 }]));
console.log(simple({ A: 1, B: 2 }));
.as-console-wrapper { max-height: 100% !important; top: 0; }
I'm new to StackOverflow and I know this post might possibly be a duplicate of another so please spare me with all the downvotes and if you think there's an answer to my question out there, please post it and I'll delete this question. Thanks for understanding.
var array1 = ["name", "title", "desc"]
var array2 = [["name1", "name2"], ["title1", "title2"],["desc1", "desc2"]]
How will I turn these into:
[
{name: "name1", title: "title1", desc: "desc1"},
{name: "name2", title: "title2", desc: "desc2"}
]
You can use Array#map, Object.assign (with spread syntax) and the ES6 computed property syntax to achieve that:
const array1 = ["name", "title", "desc"],
array2 = [["name1", "name2"], ["title1", "title2"],["desc1", "desc2"]];
const result = array2[0].map( (_, j) =>
Object.assign(...array1.map( (key, i) => ({ [key]: array2[i][j] }) ))
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
const result = [];
for(const [index, key] of array1.entries()){
for(const [userindex, value] of array2[index].entries()){
if(!result[userindex])
result[userindex] = {};
result[userindex][key] = value;
}
}
You might go over every key and the values related to the key and assign every key/value pair to the resulting object at the position of the value.
You could reduce the given values array by using the keys as key and the value for new objects.
var keys = ["name", "title", "desc"],
values = [["name1", "name2"], ["title1", "title2"],["desc1", "desc2"]],
objects = values.reduce((r, a, i) => {
a.forEach((v, j) => Object.assign(r[j] = r[j] || {}, { [keys[i]]: v }));
return r;
}, []);
console.log(objects);
You can use this way also:
var array1 = ["name", "title", "desc"];
var array2 = [["name1", "name2"], ["title1", "title2"],["desc1", "desc2"]];
var res = [];
for(var i=0; i<array2[0].length; i++){
var obj = {};
for(var j=0; j<array1.length; j++){
var key = array1[j];
var value = array2[j][i];
obj[key] = value;
}
res.push(obj);
}
console.log(res);