How to Convert Object to Array in Javascript - javascript

I'd like to convert an object to an array of smaller, single-property objects in Javascript.
For example:
x={
a: {a1:"a1", a2:"a2"},
b: {b1:"b1", b2:"b2"},
c: {c1:"c1", c2:"c2"}
}
converted to
y=[
{a: {a1:"a1", a2:"a2"}},
{b: {b1:"b1", b2:"b2"}},
{c: {c1:"c1", c2:"c2"}}
]
I know this is possible with loops, but I was wondering if there is a more elegant way. I'm using underscore/lo-dash if they help.

You could use Array#map for it.
var x = { a: { a1: "a1", a2: "a2" }, b: { b1: "b1", b2: "b2" }, c: { c1: "c1", c2: "c2" } },
y = Object.keys(x).map(function (k) {
var o = {};
o[k] = x[k];
return o;
});
console.log(y);
ES6 #Nenad Vracar
var x = { a: { a1: "a1", a2: "a2" }, b: { b1: "b1", b2: "b2" }, c: { c1: "c1", c2: "c2" } },
y = Object.keys(x).map(k => ({[k]: x[k]}));
console.log(y);

As Barmar pointed out, it does make more sense to use map (I left my reduce versions for posterity):
let arr = Object.keys(x).map(key => { [key]: x[key] });
You can use reduce to turn it into an array:
Object.keys(x).reduce(function(acc, key) {
var tmp = {};
tmp[key] = x[key];
acc.push(tmp);
return acc;
}, []);
And if ES6 is available, you can make it a bit more concise:
Object.keys(x).reduce((acc, key) => {
acc.push({ [key]: x[key] });
return acc;
}, []);

Related

Find matching object keys from an array of objects

Given an array of objects all with the same property names, with javascript how would you create a new object made up of key:value pairs that are found in all the objects of the array?
For example, given:
[
{
a: 'foo',
b: 'bar',
c: 'zip'
},
{
a: 'urg',
b: 'bar',
c: 'zip'
},
{
a: 'foo',
b: 'bar',
c: 'zip'
}
]
Result:
{
b: 'bar',
c: 'zip'
}
Start with all the elements of the first item (cloned, because we don't want to change the original data), then remove any key-value pairs that do not show up in the subsequent items:
const data = [
{
a: 'foo',
b: 'bar',
c: 'zip'
},
{
a: 'urg',
b: 'bar',
c: 'zip'
},
{
a: 'foo',
b: 'bar',
c: 'zip'
}
];
const [first, ...rest] = data;
const result = rest.reduce((a, e) => {
Object.keys(a).forEach(k => {
if (!k in e || e[k] !== a[k]) {
delete a[k];
}
});
return a;
}, {...first});
console.log(result);
Just compare each value in the first object with every other object.
const [first, ...others] = [
{
a: 'foo',
b: 'bar',
c: 'zip'
},
{
a: 'urg',
b: 'bar',
c: 'zip'
},
{
a: 'foo',
b: 'bar',
c: 'zip'
}
];
for (const [key, value] of Object.entries(first)) {
for (const object of others) {
if (object[key] !== value) {
delete first[key];
}
}
}
console.log(first);

Union two objects, but omit falsy values

How can I union two objects, but omit to merge falsy values like 0, "", false, from the second object?
I want it to work in both ways and doesn't depend on the order i pass the objects
So this example is not an options: const union = {...obj2, ...obj1};
const obj1 = {a: 1, b: 2, c: { c1: 12, c2: 15 }};
const obj2 = {a: 1, b: 2, c: { c1: 0, c2: 0 }, d: 3};
const union = {...obj1, ...obj2};
console.log(union);
Desired output:
{
"a": 1,
"b": 2,
"c": {
"c1": 12,
"c2": 15
},
"d": 3
}
You could take a recursive funtion to merge nested objects with a condition.
function union(a, b) {
return [a, b].reduce((r, o) => {
Object.entries(o).forEach(([k, v]) => {
if (!v) return;
r[k] = typeof v === 'object'
? union(r[k] || {}, v)
: v;
})
return r;
}, {});
}
console.log(union(
{ a: 1, b: 2, c: { c1: 12, c2: 15 } },
{ a: 1, b: 2, c: { c1: 0, c2: 0 }, d: 3 }
));

Divide object in array of arrays using keys

Consider the following object :
{ a1: "Foo", b1: "Boo" , c1: "Coo", a2: "Doo" , b2: "Goo", c2: "Soo", ....... c50: "Zoo" }
I want to divide this in an array of arrays that will look like this :
[["Foo","Boo","Coo"], ["Doo","Goo","Soo"]......[ .., ..,"Zoo"]]
What is the best practice for doing that ?
You can first use reduce() on Object.keys() to return one object and then map() keys of that object to return values which will be array of values.
var obj = { a1: "Foo", b1: "Boo" , c1: "Coo", a2: "Doo" , b2:"Goo", c2:"Soo", c50:"Zoo"}
var o = Object.keys(obj).reduce(function(r, e) {
var newKey = e.match(/\d+/)[0]
r[newKey] = (r[newKey] || []).concat(obj[e])
return r
}, {})
var result = Object.keys(o).map(e => o[e])
console.log(result)
With ES-7 you could use Object.values() but it still has bad browser support, but the solution looks like this.
var obj = { a1: "Foo", b1: "Boo" , c1: "Coo", a2: "Doo" , b2:"Goo", c2:"Soo", c50:"Zoo"}
var result = Object.values(Object.keys(obj).reduce(function(r, e) {
var newKey = e.match(/\d+/)[0]
return r[newKey] = (r[newKey] || []).concat(obj[e]), r
}, {}))
console.log(result)
You could get the keys with Object.keys, iterate with Array#forEach over them, get the numerical part with String#match, decrement it for the index and push the value.
var object = { a1: "Foo", b1: "Boo" , c1: "Coo", a2: "Doo" , b2:"Goo", c2:"Soo", c50:"Zoo"},
result = [];
Object.keys(object).forEach(function (key) {
var i = key.match(/\d+$/) - 1;
result[i] = result[i] || [];
result[i].push(object[key]);
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Try something like this:
var obj = { a1: "Foo", b1: "Boo" , c1: "Coo", a2: "Doo" , b2:"Goo", c2:"Soo" };
var indexObj = { a: 0, b: 1, c: 2 };
var result = [];
for(var prop in obj) {
var index = indexObj[prop[0]];
var array = prop.match(/\d+$/) - 1;
if(!result[array]) {
result[array] = [];
}
result[array][index] = obj[prop];
}
console.log(JSON.stringify(result));
//[["Foo","Boo","Coo"],["Doo","Goo","Soo"]]
May be you can do as follows;
var obj = { a1: "Foo", b1: "Boo" , c1: "Coo", a2: "Doo" , b2: "Goo", c2: "Soo", a3: "Hello", b3: "to", c3: "you", c50: "Zoo" },
res = Object.keys(obj)
.reduce(function(r,c){
var t = /\d+/.exec(c)[0];
r.t = r.t !== t ? (r.push([obj[c]]), t)
: (r[r.length-1].push(obj[c]), t);
return r;
},[]);
console.log(res);

how to filter data in array loop 222

Previously I asked this question, (how to filter data in array loop) but I have some changes in my second array,.. as given below..
In my array is like this,
var myColumnDefs = [
{a: "hh", b: "hh", c: "jk", d: "ggh", e: "hvh"},
{a: "dd", b: "gg", d: "nn", e: "rr", f: "jj"},.....
]
I want to filter data and insert data in new array like this
var newarray = {a,b,c,d,e,f}
& another array
var mysecondarray = [
{hh,hhjk,ggh,hvh,null},
{dd,gg,null,nm,rr,jj},....
]
First collect every key, then collect the data.
var myColumnDefs = [{ a: "hh", c: "jk", d: "ggh", e: "hvh" }, { a: "dd", b: "gg", d: "nn", e: "rr", f: "jj" }],
result = function (array) {
var r = { keys: [], data: [] }, o = {};
array.forEach(function (a) {
Object.keys(a).forEach(function (k) {
if (!(k in o)) {
o[k] = r.keys.push(k) - 1;
}
});
});
r.keys.sort(); // sort all keys
array.forEach(function (a) {
r.data.push(r.keys.map(function (k) {
return a[k];
}));
});
return r;
}(myColumnDefs);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

Javascript: check difference in two objects (inner)

I'm using such code for checking, if two objects are not equal.
(i'm creating patch query string):
var concatUnique = function(a, b) {
if (b.length === 0) return a;
return a.indexOf(b[0]) === -1 ? concatUnique(a.concat(b[0]), b.slice(1)) : concatUnique(a, b.slice(1));
};
var diffObject = function(a, b) {
return concatUnique(Object.keys(a), Object.keys(b)).reduce(function(map, k) {
if (a[k] !== b[k]){
if (angular.isArray(b[k])){
if (a[k].toString() !== b[k].toString()){
map[k] = b[k];
}
}
else{
map[k] = b[k];
}
}
return map;
}, {});
};
var compareTwoObjects = function(initialObj, editedObj) {
var result = diffObject(initialObj, editedObj);
return JSON.stringify(result);
};
but i have one case:
for example i have such two objects:
{a: "1", b: "2", sub: {"1", "2"}}
&
{a: "1", b: "2", sub: {"1", "3"}}
my code will work, but!
if i have such object:
{a: "1", b: "2", sub: {c: "1", d: "2"}}
&
{a: "1", b: "2", sub: {c: "1", d: "3"}}
it will not work
why it's not using inner object keys?

Categories

Resources