Create array data structure from nested object of arrays in JS - javascript

I have a data structure as follows:
UPDATED: to have more than one object in innerValues
const data = {
"dates": [
"2015-09-09T00:00:00",
"2015-09-09T00:10:00",
"2015-09-09T00:20:00",
],
"innerValues": [
{
"name": "Name_1",
"value": [
104,
105,
107,
]
},
{
"name": "Name_2",
"value": [
656,
777,
145,
]
}],
}
I would like to create an output like:
const outPut = [
["2015-09-09T00:00:00", 'Name_1', 104 ],
["2015-09-09T00:10:00", 'Name_1', 105 ],
["2015-09-09T00:20:00", 'Name_1', 107 ],
["2015-09-09T00:00:00", 'Name_2', 104 ],
["2015-09-09T00:10:00", 'Name_2', 105 ],
["2015-09-09T00:20:00", 'Name_2', 107 ]
]
So far I have this, I know I could do this with forEach etc also - but as an example.
const m = data.dates;
let arr = [];
for (var i = 0; i < m.length; i++) {
arr[i] = new Array(m[i]);
}
console.log(arr);
This gives:
0: ['2021-09-09T00:00:00']
1: ['2021-09-09T00:10:00']
2: ['2021-09-09T00:20:00']
Which is where I want to start, however if I map over inner.values and try to create an new array from that, it does not return three separate arrays but one.e.g
const newArray = x.forEach(inner => console.log(new Array(inner)))
Output
0: (3) [104, 105, 107]
How could I achieve the above desired structure.

You can use reduce and map to loop over innerValues and their values
const dates = data.dates
const newArr = data.innerValues.reduce((acc, cur, i) => {
acc.push(cur.value.map((value, i) => ([dates[i], cur.name, value])));
return acc;
}, []).flat()
console.log(newArr)
<script>
const data = {
"dates": [
"2015-09-09T00:00:00",
"2015-09-09T00:10:00",
"2015-09-09T00:20:00",
],
"innerValues": [{
"name": "Name_1",
"value": [
104,
105,
107,
]
},
{
"name": "Name_2",
"value": [
656,
777,
145,
]
}
],
}
</script>

Related

How can I get the last items from a nested array?

I was struggling to get the last object item from a nested array. I tried to implement flatMap, flat, filter, and splice. However, I can not still get the expected array.
const array = [
[
{
total_cases: 18,
},
{
total_cases: 32,
},
{
total_cases: 7,
},
],
[
{
total_cases: 4,
},
{
total_cases: 52,
},
],
[
{
total_cases: 68,
},
],
];
I have an array like the above. How can I get only the last-object item into a new array?
Expected new array should be like this:
[7, 52, 68]
Thanks in advance!
You can use .at() method. Negative parametr count back from the last item in the array. So .at(-1) return the last array's element.
const array=[[{total_cases:18},{total_cases:32},{total_cases:7}],[{total_cases:4},{total_cases:52}],[{total_cases:68}]];
const result = array.map(e => e.at(-1).total_cases);
console.log(...result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Edit based on changes to question.
You can use map and slice to select only the last element of each nested array, then flat to flatten the array and map again to select the total_cases values:
const array = [
[
{ total_cases: 18 },
{ total_cases: 32 },
{ total_cases: 7 },
],
[
{ total_cases: 4 },
{ total_cases: 52 },
],
[
{ total_cases: 68 },
],
];
const result = array
.map(a => a.slice(a.length - 1))
.flat(1)
.map(o => o.total_cases)
console.log(result)
Original Answer
You can flatten the array, filter it based on the date value and then use map to extract the total_cases values:
const array = [
[
{
date: "2020-02-25",
total_cases: 18,
},
{
date: "2020-02-26",
total_cases: 32,
},
{
date: "last-object",
total_cases: 7,
},
],
[
{
date: "2020-02-26",
total_cases: 4,
},
{
date: "last-object",
total_cases: 52,
},
],
[
{
date: "last-object",
total_cases: 68,
},
],
];
const result = array
.flat(1)
.filter(o => o.date == 'last-object')
.map(o => o.total_cases)
console.log(result)

Merging multiple arrays inside an objects into a single array

My Object contains different datatypes including array. I want to concatenate all arrays(in a single array)
I have written using foreach and concat.
Is there any way I can have a better solution, or this is correct?
See the below snippet. concat array value3 and value5 into single array.
var Input = {
"value1": 10,
"value2": "abcd",
"value3": [
{
"v1": 100,
"v2": 89
},
{
"v1": 454,
"v2": 100
}
],
"value4": "xyz",
"value5": [
{
"v6": 1,
"v7": -8
},
{
"v1": 890,
"v2": 10
}
]
}
var OutputData = [];
let keys = Object.keys(Input);
keys.forEach(key => {
if (Array.isArray(Input[key])) {
try {
OutputData= OutputData.concat(Input[key])
} catch (error) {
}
}
});
console.log(OutputData)
You could use Array.prototype.filter() with Array.prototype.flat() method get a cleaner code. First get all the values using Object.values() method. Then use filter method to get the arrays and at last use flat method to get a new array with all sub-array elements concatenated.
const input = {
value1: 10,
value2: 'abcd',
value3: [
{
v1: 100,
v2: 89,
},
{
v1: 454,
v2: 100,
},
],
value4: 'xyz',
value5: [
{
v6: 1,
v7: -8,
},
{
v1: 890,
v2: 10,
},
],
};
const ret = Object.values(input)
.filter((x) => Array.isArray(x))
.flat();
console.log(ret);
I think this might be a little bit cleaner to read:
var input = {
"value1": 10,
"value2": "abcd",
"value3": [{
"v1": 100,
"v2": 89
},
{
"v1": 454,
"v2": 100
}
],
"value4": "xyz",
"value5": [{
"v6": 1,
"v7": -8
},
{
"v1": 890,
"v2": 10
}
]
};
let res = [];
for (let k in input) {
if (input.hasOwnProperty(k) && Array.isArray(input[k]))
input[k].forEach(x => res.push(x));
}
console.log(res);

How to do Math.random() in for-loop with different values?

I try to fill the array s with 9999 different sets of values m[i][random], here is the code:
let m = [[22,0],[53,0],[64,0],[45,0],[34,0]];
let l = m.length;
let s = [];
for (let j = 0; j < 9999; j++)
{
for(let i = 0; i < m.length; i++)
{
let x = Math.floor(Math.random()*l);
m[i][1] = x;
}
s.push(m);
}
But i get the same values:
console.log(s)
[ [ [ 22, 0 ], [ 53, 2 ], [ 64, 0 ], [ 45, 4 ], [ 34, 1 ] ],
[ [ 22, 0 ], [ 53, 2 ], [ 64, 0 ], [ 45, 4 ], [ 34, 1 ] ],
[ [ 22, 0 ], [ 53, 2 ], [ 64, 0 ], [ 45, 4 ], [ 34, 1 ] ],
[ [ 22, 0 ], [ 53, 2 ], [ 64, 0 ], [ 45, 4 ], [ 34, 1 ] ],
[ [ 22, 0 ], [ 53, 2 ], [ 64, 0 ], [ 45, 4 ], [ 34, 1 ] ],
[ [ 22, 0 ], [ 53, 2 ], [ 64, 0 ], [ 45, 4 ], [ 34, 1 ] ],
[ [ 22, 0 ], [ 53, 2 ], [ 64, 0 ], [ 45, 4 ], [ 34, 1 ] ], ...]
What am I doing wrong? How to fix it?
Create the m subarray inside the loop (so you have a separate subarray for each iteration), not outside of it - outside, you've only created a single array in memory that each index points to.
let s = [];
for (let j = 0; j < 9999; j++)
{
let m = [[22,0],[53,0],[64,0],[45,0],[34,0]];
let l = m.length;
for(let i = 0; i < m.length; i++)
{
let x = Math.floor(Math.random()*l);
m[i][1] = x;
}
s.push(m);
}
Or, more functionally and all at once with Array.from:
const s = Array.from(
{ length: 2 },
() => [[22,0],[53,0],[64,0],[45,0],[34,0]]
.map(([num]) => [num, Math.floor(Math.random() * 5)])
);
console.log(s);

Mege multiple array object into single array object based on key

I have an array of objects of the structure coming from server response of iterated array object like as sample
var arrObj1 = [
{"id":"1","value":21, "value1":13},
{"id":"2","value":21, "value1":13 },
......n
];
var arrObj2 = [
{"id":"1","value3":21, "value14":13},
{"id":"2","value3":21, "value4":13 },
......n
];
var arrObj3 = [
{"id":"1","value5":21, "value6":13},
{"id":"2","value5":21, "value6":13 },
......n
];
But now I want to append the array values inot single new array according to key following structure of as iterated values of above array Expected Output:
var finalObj = [
{
"id" : 1
"value" : 21,
"value1" : 13,
"value3" : 21,
"value4" : 13,
"value5" : 21,
"value6" : 13,
},
{
"id" : 2
"value" : 21,
"value1" : 13,
"value3" : 21,
"value4" : 13,
"value5" : 21,
"value6" : 13,
},
.....n
];
You can use reduce for concated arrays
const arrObj1 = [
{ id: '1', value: 21, value1: 13 },
{ id: '2', value: 21, value1: 13 },
];
const arrObj2 = [
{ id: '1', value3: 21, value14: 13 },
{ id: '2', value3: 21, value4: 13 },
];
const arrObj3 = [
{ id: '1', value5: 21, value6: 13 },
{ id: '2', value5: 21, value6: 13 },
];
const result = [...arrObj1, ...arrObj2, ...arrObj3].reduce(
(acc, { id, ...rest }) => ({ ...acc, [id]: acc[id] ? { ...acc[id], ...rest } : { ...rest } }),
{},
);
console.log(Object.entries(result).map(([id, data]) => ({ id, ...data })));
Push you arrays to a new array (you have to have your sub arrays in other list to loop through them) and then use flat, after that group your object according to the id property
var arrObj1 = [{
"id": "1",
"value": 21,
"value1": 13
},
{
"id": "2",
"value": 21,
"value1": 13
},
];
var arrObj2 = [{
"id": "1",
"value3": 21,
"value14": 13
},
{
"id": "2",
"value3": 21,
"value4": 13
},
];
var arrObj3 = [{
"id": "1",
"value5": 21,
"value6": 13
},
{
"id": "2",
"value5": 21,
"value6": 13
},
];
const input = [];
input.push(arrObj2, arrObj3);
const preResult = input.flat();
result = preResult.reduce((acc, x) => {
const index = acc.findIndex(y => y.id === x.id)
if (index >= 0) {
acc[index] = {
...acc[index],
...x
}
} else {
acc.push(x)
}
return acc;
}, arrObj1)
console.log(result)
You can iterate over array-length and push here for every entry 1 entry to the result. For getting this entry take a new object with the id and iterate over all (3 or perhaps more) arrays. For every array take the i-th entry and push for every key an entry with key:value (except for the key id itself).
Remark: You can use as much arrays you want and every object could contain as much value-prperties as you need. The only restriction is that every array has the same count of objects.
var arrObj1 = [
{"id":"1","value":21, "value1":13},
{"id":"2","value":21, "value1":13 }
];
var arrObj2 = [
{"id":"1","value3":21, "value4":13},
{"id":"2","value3":21, "value4":13 }
];
var arrObj3 = [
{"id":"1","value5":21, "value6":13},
{"id":"2","value5":21, "value6":13 }
];
let result =[];
let arrayAll = [arrObj1, arrObj2, arrObj3];
for (let i=0; i<arrayAll[0].length; i++) {
let obj = arrayAll[0][i];
let res = { id: obj.id};
for (let j=0; j<arrayAll.length; j++) {
let obj = arrayAll[j][i];
Object.keys(obj).forEach(key => {
if (key!='id') res[key] = obj[key];
})
}
result.push(res);
}
console.log(result);
Since you are using id to merge multiple objects, Map is one of the good option to merge.
let arrObj1 = [
{"id":"1","value":21, "value1":13},
{"id":"2","value":21, "value1":13 },
];
let arrObj2 = [
{"id":"1","value3":21, "value14":13},
{"id":"2","value3":21, "value4":13 },
];
let arrObj3 = [
{"id":"1","value5":21, "value6":13},
{"id":"2","value5":21, "value6":13 },
];
let mergedArray = [...arrObj1,...arrObj2,...arrObj3].reduce((acc,curr) =>{
if(acc.has(curr.id)){
acc.set(curr.id, {...acc.get(curr.id),...curr});
}else{
acc.set(curr.id,curr);
}
return acc;
},new Map())
console.log(Array.from(mergedArray,x=>x[1]));

Converting an object with multiple arrays to a multi dimensional array

I have this format:
Data = {
"count": [ 62, 58, 10, 6 ],
"categoires": [ "a1", "a2", "a3", "a4" ]
}
I need to get get data in to the following format:
data = [
[ "a1", 62 ],
[ "a2", 58 ],
[ "a3", 10 ],
[ "a4", 6 ]
]
Can anyone help me do this?
Try using while loop
var data = {
"count": [62, 58, 10, 6],
"categoires": ["a1", "a2", "a3", "a4"]
}
var res = [], // array to push values to
i = 0, // begin at index `0`
len = data["categoires"].length; // max length
while (i < len) {
res.push([data["categoires"][i], data["count"][i]]); // push data tob `res`
++i; // increment index
}
console.log(res);
document.body.textContent = JSON.stringify(res, null, 2)
body {
white-space:pre;
}
You can loop using for and length properties:
var data = [];
for (var i = 0; i < Data.count.length; i++)
data[i] = [ Data.categoires[i], Data.count[i] ];

Categories