Array with levels - each level has values - javascript

I'm trying to create an array that has multiple levels and multiple values on each level. It needs to look something like this:
Value 1 level 1
Value 1 level 2
Value 1 level 3
Value 2 level 2
Value 2 level 1
How can I put something like this in an array?

You can make each level as a new array.
var myArray = new Array("Value 1 level 1", "Value 2 level 1");
myArray['Value 1 level 1'] = new Array("Value 1 level 2", "Value 2 level 2");
myArray['Value 2 level 2'] = new Array("Value 1 level 3");

you can have an array of objects like the below structure
var value=
{
value1level1:
{
value1level2:
{
value1level3:'somevalue'
}
}
};
var parentObj=[value];

Create a JSON structure like this:
[
{
"node":{
"Value 1":"level 1"
},
"children":[
{
"node":{
"Value1":"level 2"
},
"children":[
{
"node":{
"Value1":"level 3"
},
"children":[
]
}
]
}
]
},
{
"node":{
"Value 2":"level 1"
},
"children":[
]
}
]

Related

Is there a way to de-dupe a javascript array and combine values of the data?

I'm using an ajax request to grab some XML data which I then need to push into a chart in fusioncharts.
The XML data is formatted as [time taken], [work done], [which team done for], [who did it] (see below).
I'm iterating over the XML and then building the array using the code below:
//Time Recorded
if (columnidchecker == 7781) {
timearray.push($j(this).find('displayData').text());
temp1 = $j(this).find('displayData').text();
}
//Type of Activity
if (columnidchecker == 7782) {
activityarray.push($j(this).find('displayData').text());
temp2 = $j(this).find('displayData').text();
}
//Team Done For
if (columnidchecker == 7783) {
subjectarray.push($j(this).find('displayData').text());
temp3 = $j(this).find('displayData').text();
}
//Name
if (columnidchecker == 7777) {
internalclientarray.push($j(this).find('displayData').text());
temp4 = $j(this).find('userDisplayName').text();
}
});
//PUSH INTO A NEW ARRAY WHICH CAN THEN BE SORTED AND DE-DUPED WITH TIME COMBINED AGAINST ACTIVITY / TEAM.
objectarray.push([temp1, temp2, temp3, temp4]);
This builds an array of entries from the XML which basically outputs to something which looks like this:
0: (4) ["1.50", "Ad-hoc queries or calls", "Team 1", "James"]
1: (4) ["2.50", "Ad-hoc queries or calls", "Team 1", "James"]
2: (4) ["1.00", "Advice", "Team 2", "James"]
3: (4) ["3.50", "Meeting (External 3rd Party)", "Team 1", "James"]
4: (4) ["1.20", "Administration", Team 2", "James"]
5: (4) ["5.50", "Advice", "Team 1", "John"]
I'm trying to build a chart in fusioncharts which needs the format as shown below (ignore foot stuffs - it's taken straight from the fusioncharts help pages!).
{
"chart": {
"theme": "fusion",
"caption": "Revenue split by product category",
"subCaption": "For current year",
"xAxisname": "Quarter",
"yAxisName": "Revenues (In USD)",
"showSum": "1",
"numberPrefix": "$"
},
"categories": [
{
"category": [
{
"label": "Q1"
},
{
"label": "Q2"
},
{
"label": "Q3"
},
{
"label": "Q4"
}
]
}
],
"dataset": [
{
"seriesname": "Food Products",
"data": [
{
"value": "11000"
},
{
"value": "15000"
},
{
"value": "13500"
},
{
"value": "15000"
}
]
},
{
"seriesname": "Non-Food Products",
"data": [
{
"value": "11400"
},
{
"value": "14800"
},
{
"value": "8300"
},
{
"value": "11800"
}
]
}
]
}
The problem i'm having is that I cannot work out how to take the array of data with times, activity, team, name and push them into categories.
I think the first step is to create a new array of names which can be pushed into the "Category" data field in fusioncharts.
I then need a way in which to take the times being recorded against each activity and for each team and make sure it's assigned to the right person within the stacked bar chart and combine the amount of time spent. (i.e. "James" spent a total of 4 hours doing "Ad Hoc Queries and Calls" for Team 1 but this is split across two time entries so I need a way in which to combine them into one.)
Any help on this would be massively appreciated.
I can de-dupe the names to create a new array by using the following code:
namesarray.push(temp4);
uniq = [...new Set(namesarray)];
but after that it starts getting pretty complicated.
Maybe this can help you along the way. It's probably not exactly in the form you want it, but it demonstrates how you could break the problem down into smaller parts.
Pseudo-code:
get the unique names.
get the unique "task" names (for lack of a
better word)
for each unique person name:
3.1. get the data rows for that person
3.2 for each of all unique tasks names:
find the person data rows matching the task name
sum the duration of those data rows
const testData = [
[
"1.50",
"Ad-hoc queries or calls",
"Team 1",
"James"
],
[
"2.50",
"Ad-hoc queries or calls",
"Team 1",
"James"
],
[
"1.00",
"Advice",
"Team 2",
"James"
],
[
"3.50",
"Meeting (External 3rd Party)",
"Team 1",
"James"
],
[
"1.20",
"Administration",
"Team 2",
"James"
],
[
"5.50",
"Advice",
"Team 1",
"John"
]
];
const columnIndexByName = {
TASK_DURATION: 0,
TASK_NAME: 1,
FOR_WHICH_TEAM: 2,
PERSON_DOING_TASK: 3
};
const sum = (acc, next) => acc + next;
const uniqueNames = [...new Set(testData.map(row => row[columnIndexByName.PERSON_DOING_TASK])) ];
const uniqueTaskNames = [...new Set(testData.map(row => row[columnIndexByName.TASK_NAME])) ];
let result = {};
uniqueNames.forEach(personName => {
const personDataRows = testData.filter(row => row[columnIndexByName.PERSON_DOING_TASK] === personName);
let taskDurationsByTaskName = {};
uniqueTaskNames.forEach(taskName => {
const taskRows = personDataRows.filter(row => row[columnIndexByName.TASK_NAME] === taskName);
const taskDurations = taskRows.map(row => Number.parseFloat( row[columnIndexByName.TASK_DURATION] ));
const taskTotalDuration = taskDurations.reduce(sum, 0);
taskDurationsByTaskName[taskName] = taskTotalDuration;
})
result[personName] = taskDurationsByTaskName;
})
const renderData = data => document.querySelector("#output").innerHTML = JSON.stringify(data, null, 2);
renderData(result);
<pre id="output"></pre>

How to get nth level of parsed json?

I have a JSON that has three levels and it's stored as Array I need to get 2nd level(count started from 0) and below in each level has 10+ elements. How it can be implemented on JavaScript.Need your help. All response will be helpful.
ps. some 1st level and 2nd level elements can be empty
[
{
"name": "0th level first", //0th level
"options": [
{
"name": "1st level Cafe", // 1st level
"options": [
{
"name": "2nd level Staff", //2nd level
"options": [
{
"name": "Gary", //3rd level
"age": 18
},
{
"name": "James", //3rd level
"age": 25
}
]
}
]
}
]
}
]
Probably this one? :)
data.forEach((value, index) => {
for(stage0 in value){
if(typeof value[stage0] === 'object'){
value[stage0].forEach((val, index) => {
for(stage1 in val){
if(typeof val[stage1] === 'object'){
val[stage1].forEach((val2, index) => {
for(stage2 in val2){
console.log(val2[stage2]);
}
})
}
}
})
}
}
})
You can use array.forEach which will be only iterating through each level.
on first loop there is a property call options which is an array, you need to loop through the options array in 0 level, on the second loop again one more options array comes you need to again loop through the options array which is 1 level.
then you reach the thrid level which is your output.
Third level means starting from zero its second level.
I hope this will solve the issue.
var data = [
{
"name": "0th level first", //0th level
"options": [
{
"name": "1st level Cafe", // 1st level
"options": [
{
"name": "2nd level Staff", //2nd level
"options": [
{
"name": "Gary", //3rd level
"age": 18
},
{
"name": "James", //3rd level
"age": 25
}
]
}
]
}
]
}
]
data.forEach(fl => {
fl.options.forEach(sl => {
sl.options.forEach(tl => {
console.log("second level starting from 0",tl)
})
})
})
Assume data contains your json, we have 2 onliners:
let out = data[0].options[0].options[0];
let outArr = data.flatMap(x=>x.options.flatMap(y=>y.options));
results
// out = {"name":"2nd level Staff","options":[{"name":"Gary","age":18},{"name":"James","age":25}]}
// outArr = [{"name":"2nd level Staff","options":[{"name":"Gary","age":18},{"name":"James","age":25}]}]
First one (out) contains one 2nd element. We use here tree indexes here (three zeros) first data[0] return first element in array data, then options[0] return first element in options array.
The second solution (outArr) contains array of all 2nd elements. We use here JS flatMap
To write second solution inspired me abdullahkady comment below question.

Fetch data from a nested array

I would like to know if there is a way to get the length from a nested array.
My data is a JSON file like this:
{
"data" :[
"item1" :'',
"item2" :[{
"id" :1,
"text":'text'
},{
"id" :2,
"text" : 'text
}]
]
}
I'm using angular 6 and ngx-restangular.
Is possible to get the item 2 length?
The main problem is the question does not provide a valid json. A valid json for the same would be like as under :
{
"data": {
"item1": "",
"item2": [{
"id": 1,
"text": "text"
},
{
"id": 2,
"text": "text"
}
]
}
}
Now you can fetch the second element size simply by
data["item2"].length
or
data.item2.length
To extend the Answer from #AurA
If you had to work with a valid array:
[
[ "item0.0", "item0.1" ],
[ "item1.0", "item1.1" ]
]
you could access the length of the nested arrays like this:
let a = [
["item0.0", "item0.1"],
["item1.0", "item1.1"]
];
let lengthA0 = a[0].length;
let lengthA1 = a[1].length;
console.log("length of a0: ", lengthA0);
console.log("length of a1: ", lengthA1);

Concatenate two columns of an array into a new one

I have the array range with 3 columns and 10 rows.
How can I concatenate the contents of column 1 with column 2 and push them to a new range dataEnome?
I'm using the following loop, but it isn't very efficient:
var dataEnome =[];
for (i=0; i<range.length; i++){
dataEnome.push(range[i][0])+(range[i][1]);
};
The range looks like this:
For data mapping you can consider using the array.map API.
Example:
var range =
[
[ 'col1.a', 'col2.1', 'c' ],
[ 'col1.b', 'col2.2', '3' ],
[ 'col1.c', 'col2.3', '6' ],
[ 'col1.d', 'col2.4', '9' ],
[ 'col1-e', 'col2.5', '1c' ],
[ 'col1-f', 'col2.6', '6c' ],
[ 'col1-g', 'col2.7', '7c' ],
[ 'col1-h', 'col2.8', '8c' ],
[ 'col1-i', 'col2.9', '9c' ],
[ 'col1-j', 'col2.10', '0c' ],
];
var dataEnome =range.map(row => { return row[0] + row[1]});
console.log(dataEnome);
For more example usages for map;
See:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
If you want to concatenate each record from both column
You may do something like this:
var dataEnome =[];
for (i=0; i<range.getValues().length; i++){
dataEnome.push(range.getValues()[i][0]+range.getValues()[i][1]);
};
Hope this will help you.
Thanks.
... besides dataEnome.push(range[i][0])+(range[i][1]); does most probably feature a broken syntax ...
shouldn't it be dataEnome.push(range[i][0] + range[i][1]); or dataEnome.push(range[i][0].concat(range[i][1]));
... I do not consider the OP's solution to be not that efficient.
One only could transform it into a reusable and more functional style ...
function collectConcatenatedFirstTwoRowColumns(collector, row) {
collector.push(row[0].concat(" / ", row[1]));
return collector;
}
var
range = [
["0, 0", "0, 1", "0, 2"],
["1, 0", "1, 1", "1, 2"],
["2, 0", "2, 1", "2, 2"],
["3, 0", "3, 1", "3, 2"],
["4, 0", "4, 1", "4, 2"],
["5, 0", "5, 1", "5, 2"]
],
dataEnome = range.reduce(collectConcatenatedFirstTwoRowColumns, []);
console.log(dataEnome);

JavaScript looping through multimensional JSON arrays

I've been unable to locate the correct solution to my problem here. I'd like to loop through the nested Products arrays to display each Product name. Is it possible with what I've written, or do I need to re-write it in a way that allows me to query what I need easier?
[
{
"category":"A",
"products":[
{
"id":1,
"name":"Product 1",
"description":"Description of my product 1."
},
{
"id":2,
"name":"Product 2",
"description":"Description of my product 2."
},
{
"id":3,
"name":"Product 3",
"description":"Description of my product 3."
}
]
},
{
"category":"B",
"products":[
{
"id":4,
"name":"Product 4",
"description":"Description of my product 4 in cat B."
},
{
"id":5,
"name":"Product 5",
"description":"Description of my product 5 in cat B."
},
{
"id":6,
"name":"Product 6",
"description":"Description of my product 6 in cat B."
}
]
}
]
Assuming that this whole structure is in a variable called data:
data.forEach(function(category) {
if (category.hasOwnProperty('product')) {
category.products.forEach(function(product) {
console.log(product.name);
});
}
});
The outer forEach loops through all of the category objects. The inner forEach loops goes through all of the products objects in each category.
In general looping through an array things = [...] is done like this:
for( var i=0; i<thing.length; i++ ) {
// do stuff with thing[i]
}
Looping through an object things = {...} is done like this:
for( key in things ) {
if( things.hasOwnProperty(key) ) {
// do stuff with things[key] or key.
}
}
You can nest them all you like.
In your case, if we name your original data structure items, then
(see http://jsfiddle.net/7yc5arLe/):
for( item=0; item<items.length; item++ ) {
console.log('category is '+items[item].category);
for( product=0; product<items[item].products.length; product++ ) {
p = items[item].products[product];
for( key in p ) {
console.log(' product '+key+' is '+items[item].products[product][key]);
}
}
}
will output
category is A
product id is 1
product name is Product 1
product description is Description of my product 1.
product id is 2
product name is Product 2
product description is Description of my product 2.
product id is 3
product name is Product 3
product description is Description of my product 3.
category is B
product id is 4
product name is Product 4
product description is Description of my product 4 in cat B.
product id is 5
product name is Product 5
product description is Description of my product 5 in cat B.
product id is 6
product name is Product 6
product description is Description of my product 6 in cat B.
Of course it is possible.
To loop over an array [] :
for (initialization; condition; update) {
...
}
To loop over an object {} :
for (variable in object) {
if (object.hasOwnProperty(variable)) {
...
}
}

Categories

Resources