format JSON object into array of objects - javascript

I want to convert the below JSON format
let init = {
test1: [1, 2, 3, 4, 5],
test2: [6, 7, 8, 9, 10]
}
into this format using javascript native methods of array or object (supported in all browsers)
[{
test1: 1,
test2: 6
},{
test1: 2,
test2: 7
},{
test1: 3,
test2: 8
},{
test1: 4,
test2: 9
},{
test1: 5,
test2: 10
}]
I have tried with for loop and below is the code,
let keys = Object.keys(init);
let result = [];
for(let i = 0; i < keys.length; i++){
let key = keys[i];
for(let j = 0; j < init[key].length; j++){
if(i === 0){
let obj1 = {};
obj1[key] = init[key][j];
result.push(obj1);
}else{
let obj2 = result[j];
obj2[key] = init[key][j];
}
}
}

You could use Array.prototype.reduce() to do that.
Iterate on test1 array elements and push a new object to the array accumulator with test1 and test2 properties and their respective values.
let init = {
test1: [1, 2, 3, 4, 5],
test2: [6, 7, 8, 9, 10]
};
let keys = Object.keys(init);
let key1 = keys[0];
let key2 = keys[1];
let result = init[key1].reduce((acc, curr, i) => {
acc.push({
[key1]: curr,
[key2]: init[key2][i]
});
return acc;
}, []);
console.log(result);
As of now, reduce() method is supported in most of the modern browsers. For supporting all browsers, it is better to use for loop, but instead of Object.keys() iterate on object properties or use a polyfill.
let init = {
test1: [1, 2, 3, 4, 5],
test2: [6, 7, 8, 9, 10]
};
let keys = [];
for (let key in init) {
if (init.hasOwnProperty(key)) {
keys.push(key);
}
}
let key1 = keys[0];
let key2 = keys[1];
let result = [];
for (let i = 0; i < key1.length; i++) {
result.push({
[key1]: init[key1][i],
[key2]: init[key2][i]
});
}
console.log(result);

You could use a combination of for...in and Array.forEach to achieve this result in a few lines of code. If you wan't support for all browsers you can better use var instead of let though. https://caniuse.com/#search=let
var init = {
test1: [1, 2, 3, 4, 5],
test2: [6, 7, 8, 9, 10]
}
var result = []
for (var key in init) {
init[key].forEach(function (item, index) {
result[index] ? result[index][key] = item : result[index] = { [key]: item }
})
}
console.log(result)
You could maybe simplify this a bit more by initializing your result with empty objects, that would avoid using a ternary statement. That would look like this:
Disclaimer: This won't work in IE11 because of the lack of Array.fill() support
var init = {
test1: [1, 2, 3, 4, 5],
test2: [6, 7, 8, 9, 10]
}
var result = new Array(Object.keys(init)[0].length).fill().map(Object);
for (var key in init) {
init[key].forEach(function(item, index) {
result[index][key] = item
})
}
console.log(result)
If you do this make sure you don't create an array with Objects that are a reference to the same object in memory: Array.prototype.fill() with object passes reference and not new instance

Related

How to turn key value pair to new key value pair javascript

Hello can somebody help me with javascript. I have list of ages store in age.
age = [5, 5, 13, 5, 13];
The sumAge to count duplicate ages.
sumAge = age.reduce((acc, datum) => {
let count= acc[datum];
acc[datum] = count === undefined ? 1 : ++count;
return acc;
}, {});
console.log(sumAge);
I want to get my result to be like this:
{
age:5,
value: 3
},
{
age:13,
value: 2
}
Instead of this.
{
5: 3 ,
13: 2
}
I want to get my result to be like this
The structure in the question is invalid unless you mean you want an array.
Assuming you want an object keyed by the age (but keep reading if you do want an array):
const age = [5, 5, 13, 5, 13];
const sumAge = age.reduce((acc, datum) => {
let entry = acc[datum];
if (entry) {
++entry.count;
} else {
acc[datum] = {age: datum, count: 1};
}
return acc;
}, {});
console.log(sumAge);
But, this isn't really a use case for reduce, it's overcomplicated. Just use a simple for-of loop:
const age = [5, 5, 13, 5, 13];
const sumAge = {};
for (const datum of age) {
let entry = sumAge[datum];
if (entry) {
++entry.count;
} else {
sumAge[datum] = {age: datum, count: 1};
}
}
console.log(sumAge);
If you do want an array, then as Rajesh points out, just use Object.values on the result:
const age = [5, 5, 13, 5, 13];
const sumAge = {};
for (const datum of age) {
let entry = sumAge[datum];
if (entry) {
++entry.count;
} else {
sumAge[datum] = {age: datum, count: 1};
}
}
console.log(Object.values(sumAge));
Using Object.values
let age = [5, 5, 13, 5, 13];
let sumAge = age.reduce((acc, datum) => {
acc[datum] = acc[datum] || { age: datum, value: 0 };
acc[datum].value += 1;
return acc;
}, {});
console.log(Object.values(sumAge));
You could get entries of sumAge and map them as needed
let age = [5, 5, 13, 5, 13];
let sumAge = age.reduce((acc, datum) => {
let count= acc[datum];
acc[datum] = count === undefined ? 1 : ++count;
return acc;
}, {});
let arrAge = Object.entries(sumAge).map(([k,v])=>({age: Number(k), count: v}))
console.log(arrAge);
My reduce has a blank array as the initial value - this becomes the array accumulator. If the object with the key age for the is in the array, the key value is incremented by 1. Otherwise, the object for the key age with initial key value of one is added to the array accumulator. Here's my code
const checkAge = (acc, num) => acc.find(elem => elem.age == num);
const arr = [5, 15, 5, 5, 15].reduce((acc,num) => {
let idx = acc.indexOf(checkAge(acc, num))
if(idx >= 0) acc[idx].value += 1;
else acc.push({age: num, value: 1});
return acc;
}, []);
console.log(arr); //returns [{age: 5, value: 3}, {age:13, value: 2}]

Create array of objects using arrays of values

I have fairly lot of data in this form
A B C D
-------
1 2 3 4
5 6 7 8
9 1 2 3
represented using javascript types as :
df = {A: [1,5,9], B: [2,6,1], C: [3,7,2], D:[4,8,3]}
I want to convert this into this form:
[{A:1, B:2, C:3, D:4}, {A:5, B:6, C:7, D:8}, {A:9, B:1, C:2, D:3}]
I tried implementing it as:
keyes = ["A", "B", "C", "D"]
getrow = (i) => Object.assign( ...keyes.map((k) => ({[k]: df[k][i]})))
df.A.map( (x,j) => getrow(j))
But this is slow for the size of the table I have. Is there any faster way to do this?
You could use reduce and forEach loops to create array of objects.
const df = {
A: [1, 5, 9],
B: [2, 6, 1],
C: [3, 7, 2],
D: [4, 8, 3]
}
const result = Object.keys(df).reduce((r, k) => {
df[k].forEach((e, i) => {
if (!r[i]) r[i] = {}
r[i][k] = e;
})
return r;
}, [])
console.log(result)
Or maybe for better performance you can go with the for loops.
const df = {
A: [1, 5, 9],
B: [2, 6, 1],
C: [3, 7, 2],
D: [4, 8, 3]
}
const result = [];
for (let key in df) {
for (let i = 0; i < df[key].length; i++) {
if (!result[i]) result[i] = {}
result[i][key] = df[key][i]
}
}
console.log(result)
You could take two for loops, and check the existence of the object at a certain index. Then assign the value to the property.
This version is faster than the use of array methods.
var data = { A: [1, 5, 9], B: [2, 6, 1], C: [3, 7, 2], D: [4, 8, 3] },
result = [],
key, values,
i;
for ([key, values] of Object.entries(data)) {
for (i = 0; i < values.length; i++) {
if (!result[i]) result[i] = {};
result[i][key] = values[i];
}
}
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Convert two arrays into an object

var foo = { "a": [1,2,3] }
var bar = { "b": [7,8,9] }
output should look like this
[ {a: 1, b: 7}, {a: 2, b: 8}, {a:3, b: 9}]
How can I do this using ramda or javascript functional programming ?
I have done this using for loop i = 0, is it possible using functional ramda programming
If both arrays are always the same length, you can do this using map.
function mergeArrays(arr1, arr2) {
return arr1.map(function(item, index) {
return {
a: arr1[index], //or simply, item
b: arr2[index]
};
});
}
var a = [1, 2, 3];
var b = [7, 8, 9];
var joined = mergeArrays(a, b);
document.getElementById('result').innerHTML = JSON.stringify(joined, null, 2);
<pre id="result">
</pre>
You can achieve this using R.transpose to convert an array of [[1,2,3], [7,8,9]] to [[1, 7], [2, 8], [3, 9]] and then map over it with R.zipObj.
const fn = R.compose(
R.map(R.zipObj(["a", "b"])),
R.transpose
)
const a = [1, 2, 3], b = [7, 8, 9]
const result = fn([a, b])
console.log(result)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
If you would prefer to pass a and b as two arguments to fn rather than an array then you can swap R.transpose in the example above with R.unapply(R.transpose).
Assuming you want [{a:1,b:7},{a:2,b:8},{a:3,b:9}] it can be done pretty easily with map using the index to get the value in b:
var result = a.map((v, i) =>({ a: v, b: b[i] }));
i am having an array
const peopleObject = { "123": { id: 123, name: "dave", age: 23 },
"456": { id: 456, name: "chris", age: 23 }, "789": { id: 789, name:
"bob", age: 23 }, "101": { id: 101, name: "tom", age: 23 }, "102":
{ id: 102, name: "tim", age: 23 } }
for this particular i have created a code that convrts array to object i hope this is usefull for you
const arrayToObject = (array) =>
array.reduce((obj, item) => {
obj[item.id] = item
return obj
}, {})
const peopleObject = arrayToObject(peopleArray)
console.log(peopleObject[idToSelect])
Your expected output doesn't have a valid format. You should store the data in array. Like ,
var output = [];
var a = [1,2,3], b = [7,8,9];
for(var i=0; i< a.length; i++){
var temp = {};
temp['a'] = a[i];
temp['b'] = b[i];
output.push(temp);
}
You cannot store the result in an object the way you want. Objects are key-value pairs. But what you expect is only the values without keys which is not possible!
create function form ramda's addIndex and map
const data = { keys: ['a', 'b', 'c'], values: ['11', '22', '33'] }
const mapIndexed = R.addIndex(R.map)
const result = mapIndexed((item, i) => {
return { [item]: data.values[i] }
}, data.keys)
You will get an array of objects

JavaScript flatten nested array

I am trying to flatten any length of a nested array into a single array. Why it's showing array rather than array value?
function flatten(arr) {
var res = [];
for (var i = 0; i < arr.length; i++) {
if (toString.call(arr[i]) === "[object Array]") {
res.push(flatten(arr[i]));
} else {
res.push(arr[i]);
}
}
return res;
}
console.log(flatten([1, 2, [3, [4, 5, [6]]], 7, 8]));
// [1, 2, Array(2), 7, 8]
You are pushing to res the result of flatten, which is an array. Instead Array#concat the result of the inner flatten call to res, and assign the result to res.
Note: to identify an array, you can use Array#isArray.
function flatten(arr) {
var res = [];
for (var i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
res = res.concat(flatten(arr[i]));
} else {
res.push(arr[i]);
}
}
return res;
}
console.log(flatten([1, 2, [3, [4, 5, [6]]], 7, 8])); // [1, 2, Array(2), 7, 8]
You can use concat instead of push and reduce instead of for loop.
const flatten = data => data.reduce((r, e) => {
return r = r.concat(Array.isArray(e) ? flatten(e) : e), r
}, [])
console.log(flatten([1, 2, [3, [4, 5, [6]]], 7, 8]))
You can use the flat() method on the array as follows.
function flatten(arr) {
return arr.flat(10) //the number in brackets are the depth level
}
console.log(flatten([1, 2, [3, [4, 5, [6]]], 7, 8]));

Retrieving key of a JavaScript object using its index in JQUERY

I've a JavaScript object like this.
var obj = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
This JavaScript object will be totally dynamic. So I need to get the key of this JavaScript object using some index method. Like
key[1] should return "set2"
So how can I get the ID of any index from the JavaScript object?
try this:
convert the json in a array:
var obj = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
var arr = []
for (var key in obj) {
arr.push(obj[key]);
}
console.log(arr[1]);
or array of objects:
var obj = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
var arr = []
for (var key in obj) {
arr.push({key:obj[key]});
}
console.log(arr[1]);
jsfiddle:https://jsfiddle.net/3yx8a12e/
You have these options (here's JSFiddle too):
var obj = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
var sets = [];
for (var o in obj) {
if (obj.hasOwnProperty(o)) { //Thanks Magrangs for reference
sets.push(o);
};
};
//Or in modern browsers
//var sets = Object.keys(obj);
console.log(sets[1]);
You can use Object.keys(obj) to get an array of the keys of the object.
In your example, Object.keys(obj)[1] will return "set2".
Note that Object.keys is not supported in older browsers (see browser compatibility guide below):
Chrome - 5
Firefox (Gecko) - 4.0 (2.0)
Internet Explorer - 9
Opera - 12
Safari - 5
But you can polyfill it using the following code:
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
if (!Object.keys) {
Object.keys = (function() {
'use strict';
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
function getKey(data, i){
var n = 0;
for(var k in data){
if(n == i) return k;
n++;
}
}
data - your js object, i - index of member
You can Retrieve All Keys this code
var obj = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
var newary= [];
for (var x in obj) {
if (obj.hasOwnProperty(x)) { //Thanks Magrangs for reference
newary.push(x);
};
};
console.log(newary[1])
/*For Modern Browser use this code*/
// Retrieve All Keys of Object
Object.keys(obj);
// Retrieve Specific Keys of Object
Object.keys(obj)[1];

Categories