How to convert a nested object into an array of objects? - javascript

inputJson = {
"mn": {
"mt1": 1,
"mtop": 2,
"ot1": 3
},
"ln": {
"mt1": 4,
"mtop": 5,
"ot1": 6
}
}
OutputArrayOfJson=[
{ rs: "mt1", mn: 1, ln: 4 },
{ rs: "mtop", mn: 2, ln: 5 },
{ rs: "ot1", mn: 3, ln: 6 }
]
rs is hardcode Key.
I don't know why am having hard time doing this operation.

It is a conversion of javascript objects
inputJson = {
"mn": {
"mt1": 1,
"mtop": 2,
"ot1": 3
},
"ln": {
"mt1": 4,
"mtop": 5,
"ot1": 6
}
}
d = {};
for(var key1 in inputJson){
for(var key2 in inputJson[key1]) {
if(!(key2 in d)){
d[key2]={};
}
d[key2][key1] = inputJson[key1][key2];
}
}
v = [];
for(var k in d){
var o = {};
o.rs=k;
for(var k2 in d[k]){
o[k2] = d[k][k2];
}
v.push(o);
}
//result is in v
note: the next time you should shown example code or not will help

You can iterate through the object and push each root property inside an array:
var arr = [];
for (var p in inputJson){
arr.push(inputJson[p]);
}
console.log(arr);

Related

Sum every last index value with previous values in JS

I have an array:
array = {
"data": [
{ "value": [ 100, 13, 16 ] },
{ "value": [ 101, 14, 17 ] },
{ "value": [ 12, 15, 18 ] }
]
}
Which I am reformatting into a new array of just the columns:
const columnArray = jsonData.map( (current, index, arr) => {
let out = [];
for( let i = 0; i < current.value.length; i++ ) {
out.push( arr[ i ].value[ index ] );
}
return out;
});
// output
[
[ 100, 101, 12 ],
[ 13, 14, 15 ],
[ 16, 17, 18 ]
]
How would I re-write the columnArray mapping to do the column array and be able to sum from the previous value?
So the intended output from the original array would be:
[
[ 100, 201, 213 ],
[ 13, 27, 42 ],
[ 16, 33, 51 ]
]
I would also like the summing to be scalable (though it will always be in a 1:1 ratio). So if the data has 20 items, then each value will have 20 integers in that array too.
I have tried looping through but that didn't work as I only sum from the previous, not all the previous. And this wouldn't scale either:
const columnArray = jsonData.map( (current, index, arr) => {
let out = [];
for( let i = 0; i < current.value.length; i++ ) {
// dont touch first
if( i < 1 ) {
out.push( arr[ i ].value[ index ] );
} else {
out.push( arr[ i ].value[ index ] + arr[ i - 1 ].value[ index ] )
}
}
return out;
});
Instead of pushing the array element, add it to a variable accumulating the running totals, and push that.
const jsonData = [{
"value": [100, 13, 16]
},
{
"value": [101, 14, 17]
},
{
"value": [12, 15, 18]
}
];
const columnArray = jsonData.map((current, index, arr) => {
let out = [];
let total = 0;
for (let i = 0; i < current.value.length; i++) {
total += arr[i].value[index]
out.push(total);
}
return out;
});
console.log(columnArray);
or with a nested map():
const jsonData = [{
"value": [100, 13, 16]
},
{
"value": [101, 14, 17]
},
{
"value": [12, 15, 18]
}
];
const columnArray = jsonData.map((current, index, arr) => {
let total = 0;
return arr.map(el => total += el.value[index])
});
console.log(columnArray);
You're thinking this in the wrong way. You're storing the sum in the list, not anywhere else. So even tho your index is increasing, the resulting sum resides in the list, so to achieve your goal you have to save it in some variable then push the variable into the final list. Follow this code below:
const columnArray = array.data.map((current, index, arr) => {
let out = [];
let temp;
for (let i = 0; i < current.value.length; i++) {
// dont touch first
if (i < 1) {
temp = arr[i].value[index];
out.push(arr[i].value[index]);
} else {
temp = arr[i].value[index] + temp;
out.push(temp);
}
}
return out;
});
something like that...
const array0 = {
"data": [
{ "value": [ 100, 13, 16 ] },
{ "value": [ 101, 14, 17 ] },
{ "value": [ 12, 15, 18 ] }
]
}
const
rowCount = array0.data.reduce((c,{value})=>Math.max(c,value.length) ,0)
, arrResult = Array(rowCount).fill(0).map(x=>Array(array0.data.length).fill(0))
;
arrResult.forEach((_,i,arr)=>
{
array0.data[i].value.forEach((v,j)=>
{
arr[j][i] = v + (i? arr[j][i-1] : 0 )
})
})
console.log( arrResult)
.as-console-wrapper {max-height: 100%!important;top:0}

Convert key, values JSON array to tabular JSON format

I have following JSON data for Chart
var chartJson = [
{
header : '2016',
values : [1, 5, 9]
},
{
header : '2017',
values : [2, 4, 8]
},
{
header : '2018',
values : [3, 1, 5]
}
];
And needs to convert it into this format to feed my HTML table
var tableJson = [
{
2016 : 1,
2017 : 2,
2018 : 3
},
{
2016 : 5,
2017 : 4,
2018 : 1
},
{
2016 : 9,
2017 : 8,
2018 : 5
}
];
Any quick help will be appreciated to convert it into this format.
I tried using this code, but somehow missing on the logic.
let table = [];
for(var row of chartJson ){
for(var value of row.values)
{
table.push(
{
column : row.header,
value : value
});
}
}
var chartJson = [{
header: '2016',
values: [1, 5, 9]
},
{
header: '2017',
values: [2, 4, 8]
},
{
header: '2018',
values: [3, 1, 5]
}
];
let table = [];
chartJson.forEach((row, index) => {
row.values.forEach((val, j) => {
table[j] = { ...table[j],
[row.header]: val
}
});
});
console.log(table)
Iterate through every chartJson's element with its' values(through inner loop) till values' length and make an object from that.
Finally, push that object into the table array.
That's it.
Have a look at the snippet below:
var chartJson = [
{
header: '2016',
values: [1, 5, 9]
},
{
header: '2017',
values: [2, 4, 8]
},
{
header: '2018',
values: [3, 1, 5]
}
];
let table = [];
let len_of_chartJson = chartJson.length, len_of_values = chartJson[0].values.length;
for (var i = 0; i < len_of_chartJson; i++) {
let obj = {};
for (var j = 0; j < len_of_values; j++) {
obj[chartJson[j].header] = chartJson[j].values[i];
}
table.push(obj);
}
console.log(table);
let table = chartJson.reduce((tbl, rec) => {
rec.values.forEach((num, index) => {
if(!tbl[index]){
tbl[index] = {}
}
tbl[index][rec.header] = num
})
return tbl
}, [])
Array reduce function is used to loop through each object, than for each object it loop through each value, checking if the index exist in the table, if it does not exist, it create an empty object at current index. Finally it creates a key value in the current index object.
You read more about reduce function below
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

Java Script: loop through JSON

How would you loop through provided JSON to get every grade from all the years and paste them in array?I'm quite new to JS so any explanation is welcome.
Expected array for this example would be [2,4,2,5,4,5,4.5,2,3.5,5,5,5,5,5]
{
"first_name": "Ala",
"last_name": "Kowalski",
"birth_date": "29 AUG 1990",
"indeks_number": "9454530",
"year_of_study": "2",
"courses": {
"2013": {
"AlgorithmsI": {
"grades": {
"exercices": [
2,
4
],
"lecture": [
2,
5
]
}
},
"BasicPhysicsI": {
"grades": {
"exercices": [
4
],
"lecture": [
5
]
}
},
"ProgrammingI": {
"grades": {
"exercices": [
4.5
],
"lecture": [
2,
3.5
]
}
}
},
"2014": {
"ProgrammingII": {
"grades": {
"exercices": [
5
],
"lecture": [
5
]
}
},
"BasicPhysicsII": {
"grades": {
"exercices": [
5
],
"lecture": [
5
]
}
},
"AlgorithmsII": {
"grades": {
"exercices": [
5
],
"lecture": [
5
]
}
}
}
}
}
I might use JSON.stringify as a way to iterate through the object:
grades = [];
JSON.stringify(obj, function(key, value) {
if (key === 'grades')
grades = grades.concat(value.exercices, value.lecture);
return value;
});
How this works
JSON.stringify is designed to convert an object into a JSON string. To do that, it iterates over all values in the object at all levels. It also provides the ability to specify a replacer parameter, which is a function called with each key/value pair it encounters. Here, we use the replacer not to control the stringification, but to get a chance to examine each key/value pair to see if the key is 'grades', and if so add those grades to the grades array. We have to return value so that JSON.stringify keeps iterating. The actual result from JSON.stringify is irrelevant and thrown away.
Hi you can try this one.
function looop(jsonob) {
var gradeArray = [];
for (years in jsonob.courses) {
for (lessons in jsonob.courses[years]) {
for (x in jsonob.courses[years][lessons].grades.exercices) {
gradeArray.push(jsonob.courses[years][lessons].grades.exercices[x]);
}
for (x in jsonob.courses[years][lessons].grades.lecture) {
gradeArray.push(jsonob.courses[years][lessons].grades.lecture[x]);
}
}
}
return gradeArray;
}
var grades = [];
var obj = <your Object>;
processObj(obj);
function processObj(obj) {
for (var n in obj) {
if (n=='exercices' || n=='lectures') {
for (var j=0;j<obj[n].length;j++) {
grades.push(obj[n][j]);
}
} else {
processObj(obj[n]);
}
}
}
Recursive:
function each(object, iterator) {
Object.keys(object).forEach(function (key) {
var value = object[key];
iterator(value, key);
});
}
function inArray(array, value) {
return array.indexOf(value) > -1;
}
function isPlainObject(value) {
return !!value && typeof value === 'object' && value.constructor === Object;
}
function getGrades(data) {
var grades = [];
each(data, function (value, key) {
if (inArray(['exercices', 'lecture'], key)) {
grades = grades.concat(value);
} else if (isPlainObject(value)) {
grades = grades.concat(getGrades(value));
}
});
return grades;
}
You can test this in Node.js with:
var assert = require('assert');
assert.deepEqual(getGrades(fixture),
[2, 4, 2, 5, 4, 5, 4.5, 2, 3.5, 5, 5, 5, 5, 5, 5]);
Where fixture is your JSON.

Is there anything like 'lies in' operator in js, as we have '$in' in mongoose/mongo

i want to implement a function like this in js
function(arrayOfObjects, arrayOfValues, property) {
/*here i want to return all the objects of 'arrayOfObjects'
which satisfies the following condition
(index is the iterative index of array 'arrayOfObjects')
arrayOfObjects[index][property] is equivalent to any of
the values that lies in arrayOfValues */
};
example :
arrayOfObjects = [{ a: 1, b: 2 }, { a: 3, b:4 }, { a: 1, b :3 }];
arrayOfValues = [ 2, 3 ];
function(arrayOfObjects, arrayOfValues, 'b')
should return [{ a: 1, b: 2 }, { a: 1, b :3 }]
arrayOfObjects.filter(function (elem) {
return elem.hasOwnProperty(property)
&& -1 !== arrayOfValues.indexOf(elem[property]);
});
In case you need IE8 support: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter#Compatibility
You can use the Array.prototype.filter functionality:
var a1 = [{ a: 1, b: 2 }, { a: 3, b:4 }, { a: 1, b :3 }];
var a2 = [2, 3];
var filtered = a1.filter(function(item) {
return a2.indexOf(item.b) != -1;
});
No, this is too complex problem to have some build-in operator or function in JS.
You must use some cycle to walk through the elements.
function(arrayOfObjects, arrayOfValues, property) {
var result = [];
for (var i = 0; i < arrayOfObjects; i++) {
for (var j = 0; j < arrayOfValues; j++) {
if (arrayOfObjects[i][property] === arrayOfValues[j]) {
result.push(arrayOfObjects[i]);
continue; //object already added, go to next one
}
}
}
return result;
};
function fun1(arrayOfObjects, arrayOfValues, property) {
var result = new Array();
for (var obj in arrayOfObjects){
if (arrayOfObjects[obj].hasOwnProperty(property) &&
arrayOfObjects[obj][property] == arrayOfValues[property]){
result.push(arrayOfObjects[obj]);
}
}
return result;
}
var arrayOfObjects = [{ a: 1, b: 2 }, { a: 3, b:4 }, { a: 1, b :3 }];
var arrayOfValues = new Array();
arrayOfValues['a'] = 2;
arrayOfValues['b'] = 3;
console.log(fun1(arrayOfObjects , arrayOfValues , 'b'));
Your arrayOfValues should be an 'associative array' or key-value-pair object which use key to match the property. This might more suit your logic.

Javascript array. Advanced

I have JSON string from my php script like this:
var r.co = {
"A20018425":[
{"balance":"1390.31"}, // 1
{"balance":"1304.11"}, // 2
{"balance":"1188.11"}, // 3
{"balance":"1421.71"} // 4
],
"A25005922":[
{"balance":"1000"}, // 1
{"balance":"1000.86"}, // 2
{"balance":"986.32"}, // 3
{"balance":"988.96"}, // 4
{"balance":"980.26"}, // 5
{"balance":"980.16"} // 6 MAX
],
"A25005923":[
{"balance":"1001"}, // 1
{"balance":"1000.16"}, // 2
]
}
I don't know how many AXXXXXXXX elements and how many elements it contains.
To get A elements I have use the code below:
var accounts = [];
for(var key in r.co) {
if(r.co.hasOwnProperty(key)) {
accounts.push(key);
}
}
Now I know my A elements length
var accounts_length = accounts.length; // 3 for example
Now I need to know max length of elements in A:
var accounts_elements_length = [];
for (var c = 0; c < accounts.length; c++) {
accounts_elements_length.push(r.co[accounts[c]].length);
}
var accounts_elements_length_max = accounts_elements_length.max() // 6 For example
How can I get this output array for the chart?
var outputData = [{
count: 1,
A20018425: 1390.31,
A25005922: 1000,
A25005923: 1001
}, {
count: 2,
A20018425: 1304.11,
A25005922: 1000.86,
A25005923: 1000.16
}, {
count: 3,
A20018425: 1188.11,
A25005922: 986.32
}, {
count: 4,
A20018425: 1421.71,
A25005922: 988.96
}, {
count: 5,
A25005922: 980.26
}, {
count: 6,
A25005922: 980.16
}
}];
Thanks!
Just combined your algorythms:
var outputData = [];
for (var key in r.co) {
if (r.co.hasOwnProperty(key)) {
var account_length = r.co[key].length;
for (var c = 0; c < account_length; c++) {
if (outputData[c] === undefined) {
outputData[c] = { count: c+1 };
}
outputData[c][key] = r.co[key][c].balance;
}
}
}
console.log(outputData);
jsfiddle
Code :
var outputData = [];
for (var i = 0; i < 6; i++) { // filter should be - i < accounts_elements_length_max
var temp = {
'count': i + 1
};
for (var j = 0; j < accounts.length; j++) {
if (r[accounts[j]][i]) temp[accounts[j]] = r[accounts[j]][i].balance;
}
outputData.push(temp);
}
Note that i hard code the accounts_elements_length_max(6).
Output that i get:
[{
"count": 1,
"A20018425": "1390.31",
"A25005922": "1000",
"A25005923": "1001"},
{
"count": 2,
"A20018425": "1304.11",
"A25005922": "1000.86",
"A25005923": "1000.16"},
{
"count": 3,
"A20018425": "1188.11",
"A25005922": "986.32"},
{
"count": 4,
"A20018425": "1421.71",
"A25005922": "988.96"},
{
"count": 5,
"A25005922": "980.26"},
{
"count": 6,
"A25005922": "980.16"}]​
Working fiddle

Categories