Divide object in array of arrays using keys - javascript

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);

Related

How to get value from index property in javascript?

Here is my code:
const array1 = [{a: 'abc', b: 'cd'}, {a: 'abc', b: 'xyz'}, {a: 'abc',
b: 'mno'}];
let obj = array1.reduce(function(result, item, index){
result[index] = item
return result;
}, {});
let dealId = 123;
let value = {};
let array2 = [];
for (var property in obj) {
value[dealId] = array2.push(obj[property]);
}
console.log(value)
The output of this is
Object { 123: 3 }
But I want and this is what I was expecting.
Object { 123: [{a: 'abc', b: 'cd'}, {a: 'abc', b: 'xyz'}, {a: 'abc', b: 'mno'}] }
Why am I getting 3 instead of an array? How to get the array?
Array.prototype.push returns the new length of the array, not the array itself. Your loop assigns the values 1, 2 and 3 to the same value[dealId].
Instead, you can move the assignment outside the loop:
for (var property in obj) {
array2.push(obj[property]);
}
value[dealId] = array2;
Or you can simply use Object.values:
value[dealId] = Object.values(obj);
But note that this does not list inherited properties.
Why not build a new object with a single key and the given array as value?
For the object use a computed property name.
const
array = [{ a: 'abc', b: 'cd' }, { a: 'abc', b: 'xyz' }, { a: 'abc', b: 'mno' }],
key = 123,
object = { [key]: array };
console.log(object);
.as-console-wrapper { max-height: 100% !important; top: 0; }
you need to add into aaray first then create the object
const array1 = [{a: 'abc', b: 'cd'}, {a: 'abc', b: 'xyz'}, {a: 'abc', b: 'mno'}];
let obj = array1.reduce(function(result, item, index){
result[index] = item
return result;
}, {});
let dealId = 123;
let value = {};
let array2 = [];
for (var property in obj) {
array2.push(obj[property]);
}
value[dealId] = array2;
console.log(value);
const array1 = [{a: 'abc', b: 'cd'}, {a: 'abc', b: 'xyz'}, {a: 'abc',
b: 'mno'}];
let obj = array1.reduce(function(result, item, index){
result[index] = item
return result;
}, {});
let dealId = 123;
let value = {};
let array2 = [];
for (var property in obj) {
array2.push(obj[property]);
}
value[dealId] = array2;
console.log(value)
Assign your new obj property (id) the requested array:
let arr = [{a: 'abc', b: 'cd'}, {a: 'abc', b: 'xyz'}, {a: 'abc',
b: 'mno'}];
let newObj = {};
let id = 123;
newObj[id] = arr;
console.log(newObj);

New array of objects based on an array inside an object?

need to create a shallow array of objects based on the elements of an array that is an object's value:
var obj = {
a: 1,
b: 'x',
c: 'z',
d: ['rr', 'qq']
};
var rec = [];
obj.d.forEach(function(e, i) {
rec.push({
d: e
})
});
console.log(rec);
But of course this only gets me
[ { d: 'rr' }, { d: 'qq' } ]
How to get to this in a new array of objects? -->
[ { a: 1,
b: 'x',
c: 'z',
d: 'rr' },
{ a: 1,
b: 'x',
c: 'z',
d: 'qq' } ]
The easiest way to get the desired result would be to use the map function (which maps elements of one array to a new array using a given mapping function). You can then create new objects re-using a, b, and c from the original object and d from the mapping function parameters:
var rec = obj.d.map(function(r) {
return {
a: obj.a,
b: obj.b,
c: obj.c,
d: r
};
});
obj.d.forEach(function(e) {
var item = {};
Object.keys(obj).forEach(function(key) {
item[key] = obj[key];
});
item.d = e;
rec.push(item);
});
But properties a, b, c can't be objects. Otherwise each item in the rec array will have the same reference.
Alternately, this works, but it is quite ugly:
var o = {
a: 1,
b: 'x',
c: 'z',
d: ['rr', 'qq']
};
var arr = [];
Object.keys(o).forEach(function(k) {
var val = o[k];
if (Array.isArray(val)) {
val.forEach(function(j) {
arr.push({[k] : j});
});
}
});
arr.forEach(function(obj) {
for (var p in o) {
var val = o[p];
if (!Array.isArray(val)) {
obj[p] = val
}
}
});
console.log(arr);

How to Convert Object to Array in 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;
}, []);

change key/values of an object

If I have a result like this:
result = [
{ '0': 'grade', A: 'name', b1: 'number' },
{ '1': 'grade', B: 'name', b2: 'number' },
{ '2': 'grade', C: 'name', b3: 'number' }
];
How can I produce :
result = [
{ A: '0', b1: '0' },
{ B: '1', b2: '1' },
{ C: '2', b3: '2' }
];
I want to pass the analogous grade instead of name and number.
The order of keys in an object is not guaranteed. This means simply getting a key array and looping through them or accessing them by index will not work. You could make this work be detecting numeric and non-numeric keys like so:
result = [
{ '0': 'grade', A: 'name', b1: 'number' },
{ '1': 'grade', B: 'name', b2: 'number' },
{ '2': 'grade', C: 'name', b3: 'number' }
];
result.forEach(item => {
var keys = Object.keys(item);
var numericKey = keys.find(key => !isNaN(key));
var nonNumericKeys = keys.filter(key => isNaN(key));
nonNumericKeys.forEach(nonNumKey => item[nonNumKey] = numericKey);
delete item[numericKey];
});
Assuming the b3: '1' part is a typo... the following should work.
var input = [
{ '0': 'grade', A: 'name', b1: 'number' },
{ '1': 'grade', B: 'name', b2: 'number' },
{ '2': 'grade', C: 'name', b3: 'number' }
];
function reverseMap(obj){
var newObj = {};
var keys = Object.keys(obj);
for(var i=0; i<keys.length; i++){
var k = keys[i];
var v = obj[k];
newObj[v] = k;
}
return newObj;
}
var output = [];
for(var i=0; i<input.length; i++){
var reverseObj = reverseMap(input[i]);
var outputObj = {};
var number = reverseObj.grade;
outputObj[reverseObj.name] = number;
outputObj[reverseObj.number] = number;
output.push(outputObj);
}
console.log(output);
With ES6 you can use the for of loop and Objects.keys for this task:
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/let
let newResult = [];
for(let r of result) {
let keys = Object.keys(r);
let obj = {};
for(let key of keys) {
if(/\d/.test(key)) { var value = key; }
else if(/\w/.test(key)) { var key1 = key; }
else if(/\d/.test(key)) { var key2 = key; }
}
obj[key1] = value;
obj[key2] = value;
newResult.push(obj);
}
return newResult;

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>');

Categories

Resources