I do have a json array object. I need to modify it then save the modified version on a variable.
the json object
var json = [
{
"Name": "March-2016",
"Elements": [
{
"Name": "aa",
"Elements": [
{
"Name": "ss",
"Data": {
"Test1": [
22
],
"Test2": [
33
],
"Test3": [
44
],
"Test4": [
55
]
}
},
{
"Name": "ssee",
"Data": {
"Test12": [
222
],
"Test22": [
3322
],
"Test32": [
445
],
"Test42": [
553
]
}
}
]
}
]
}
];
need to be modified to
var json = [
{
"Name": "March-2016",
"Elements": [
{
"Name": "aa",
"Elements": [
{
"category": "ss",
"Test1": 22,
"Test2": 33 ,
"Test3":44,
"Test4": 55
},
{
"category": "ssee",
"Test12": 222,
"Test22": 3322 ,
"Test32":445,
"Test42": 553
}
]
}
]
}
];
I have this method but its not doing the job
var saveJson = function(arr) {
var nameValuePairs = [];
for (var i = 0, len = arr.length; i < len; i++) {
var item = arr[i];
if (item.Data) {
var newvar = {
category : item.Name
}
newvar[Object.keys(item.Data)] = Object.values(item.Data);
item = newvar
}
if (item.Elements) {
nameValuePairs = nameValuePairs.concat(saveJson(item.Elements));
}
}
return arr;
};
I need this conversion to be dynamic as for sure I will get bigger json than the posted one
sorry for the confusion and thanks in advance.
The original object is really a mess, but still you just need to step through it and pull out the values you want. This changes the json object in place:
json.forEach(item => {
item.Elements.forEach(Outer_El => {
Outer_El.Elements = Outer_El.Elements.map(item =>{
let obj = {category: item.Name}
Object.keys(item.Data).forEach(key => {
obj[key] = item.Data[key][0]
})
return obj
})
})
})
json should now look like:
[{
"Name":"March-2016",
"Elements":[
{
"Name":"aa",
"Elements":[
{
"category":"ss",
"Test1":22,
"Test2":33,
"Test3":44,
"Test4":55
},
{
"category":"ssee",
"Test1e":224,
"Test2e":334,
"Test3e":443,
"Test4e":554
}
]
}
]
}]
You can use destructuring assignment to get specific property values from an object
{
let {Name:categories, Data:{Test:[Test]}} = json[0].Elements[0].Elements[0];
json[0].Elements[0].Elements[0] = {categories, Test};
}
Related
This question already has answers here:
Find all values by specific key in a deep nested object
(11 answers)
Closed 10 months ago.
I have this JSON array tree that can include any number of nested arrays:
const namesArrayTree = [
{
"name": "Peter"
},
{
"name": "folder1",
"isArray": true,
"namesArray": [
{
"name": "Paul"
},
{
"name": "folder2",
"isArray": true,
"namesArray": [
{
"name": "Mary"
},
{
"name": "John"
}
]
}
]
},
{
"name": "Mark"
}
]
I need to transform it to a flat array including only the names:
const namesArrayFlat = [ "Peter", "Paul", "Mary", "John", "Mark" ]
So I'm using this code to do the transformation:
const namesArrayTree = [
{
"name": "Peter"
},
{
"name": "folder1",
"isArray": true,
"namesArray": [
{
"name": "Paul"
},
{
"name": "folder2",
"isArray": true,
"namesArray": [
{
"name": "Mary"
},
{
"name": "John"
}
]
}
]
},
{
"name": "Mark"
}
] ;
function getNamesList(item) {
let name = item.name;
let isArray = item.isArray;
if (isArray) {
name = item.namesArray.map(getNamesList).join("\r\n");
}
return name;
}
const namesList = namesArrayTree.map(getNamesList).join("\r\n");
const namesArrayFlat = namesList.split("\r\n");
console.log(namesArrayFlat)
The code works well, but I would like to get rid of the extra steps to create a list with the names using join.("\r\n") and then convert to array using split("\r\n").
That is, I would like to reduce the code by removing the following:
function getNamesList(item) {
let name = item.name;
let isArray = item.isArray;
if (isArray) {
/* remove code to join by "\r\n" */
name = item.namesArray.map(getNamesList)
}
return name;
}
/* remove code to create "namesList" constant and remove code to join by "\r\n") */
const namesArrayFlat = namesArrayTree.map(getNamesList)
console.log(namesArrayFlat)
(The above code still returns a tree nested arrays structure)
Any ideas about how to get rid of the extra code? also any suggestions about how to improve the code would be great, thanks!
function getNamesList(item) {
return item.isArray ? item.namesArray.map(getNamesList) : item.name
}
const names = namesArrayTree.map(getNamesList).flat(Infinity)
console.log(names)
You can achieve this with an array reducer as follows:
const namesArray = [
{
"name": "Peter"
},
{
"name": "folder1",
"isArray": true,
"namesArray": [
{
"name": "Paul"
},
{
"name": "folder2",
"isArray": true,
"namesArray": [
{
"name": "Mary"
},
{
"name": "John"
}
]
}
]
},
{
"name": "Mark"
}
] ;
function reduceNamesList(list, item) {
if (item.isArray) {
return item.namesArray.reduce(reduceNamesList, list);
}
list.push(item.name)
return list
}
const namesList = namesArray.reduce(reduceNamesList, [])
console.log(namesList)
I have a nested json array and I am trying to get the maximum value of the points attribute in this array.
data = {
"name": "KSE100",
"children": [
{
"name": "TECHNOLOGY & COMMUNICATION",
"children": [
{
"name": "TRG",
'points': -21
},
{
"name": "SYS",
},
]
},
{
"name": "OIL",
"children": [
{
"name": "PPL",
'points': 9
},
{
"name": "PSO",
'points': -19
},
]
},
]
}
I want the max value of points from under the children sections. I mean from under technology and oil sectors.
What I've done so far:
var max;
for (var i in data.children.length) {
for (var j in data.data[i]) {
var point = data.data[i].children[j]
}
}
Try the following:
data = {
"name": "KSE100",
"children": [
{
"name": "TECHNOLOGY & COMMUNICATION",
"children": [
{
"name": "TRG",
'points': -21
},
{
"name": "SYS",
},
]
},
{
"name": "OIL",
"children": [
{
"name": "PPL",
'points': 9
},
{
"name": "PSO",
'points': -19
},
]
},
]
}
var array = [];
for (var first of data.children) {
for (var second of first.children) {
if(second.points != undefined)
{
array.push(second);
}
}
}
var maximumValue = Math.max.apply(Math, array.map(function(obj) { return obj.points; }));
console.log(maximumValue);
you can use the reduce method on the array object to do this
const maxValues = []
data.children.forEach(el => {
if (el.name === 'OIL' || el.name === 'TECHNOLOGY & COMMUNICATIO'){
const max = el.children.reduce((current, previous) => {
if (current.points > previous.points) {
return current
}
}, 0)
maxValues.append({name: el.name, value: max.points})
}
})
This will give you an array of the objects with the name and max value.
First you can convert your object to a string through JSON.stringify so that you're able to use a regular expression
(?<=\"points\":)-?\\d*
To matchAll the values preceded by the pattern \"points\": that are or not negative values. After it, convert the result to a array through the spread operator ... and then reduce it to get the max value.
const data = {name:"KSE100",children:[{name:"TECHNOLOGY & COMMUNICATION",children:[{name:"TRG",points:-21},{name:"SYS"}]},{name:"OIL",children:[{name:"PPL",points:9},{name:"PSO",points:-19}]}]};
console.log(
[ ...JSON.stringify(data).matchAll('(?<=\"points\":)-?\\d*')]
.reduce((acc, curr) => Math.max(curr, acc))
)
I wasn't 100% sure, what your exact goal is, so I included a grouped max value and and overall max value with a slight functional approach.
Please be aware that some functionalities are not working in older browsers i.e. flatMap. This should anyways help you get started and move on.
const data = {
name: "KSE100",
children: [
{
name: "TECHNOLOGY & COMMUNICATION",
children: [
{
name: "TRG",
points: -21,
},
{
name: "SYS",
},
],
},
{
name: "OIL",
children: [
{
name: "PPL",
points: 9,
},
{
name: "PSO",
points: -19,
},
],
},
],
};
const maxPointsByGroup = data.children.reduce(
(acc, entry) => [
...acc,
{
name: entry.name,
max: Math.max(
...entry.children
.map((entry) => entry.points)
.filter((entry) => typeof entry === "number")
),
},
],
[]
);
console.log("grouped max:", maxPointsByGroup);
const overallMax = Math.max(
...data.children
.flatMap((entry) => entry.children.flatMap((entry) => entry.points))
.filter((entry) => typeof entry === "number")
);
console.log("overall max:", overallMax);
i have a nested array of object and i want to convert in arraylist like this :
this is my data array of object :
{
"status": true,
"message": "",
"data": [{
"pasien_docs": [{
"ecg": null,
"date": "2020-01-21T05:22:01.901Z"
}, {
"ecg": 1.03,
"date": "2020-01-21T05:22:02.979Z"
}, {
"ecg": 1.04,
"date": "2020-01-21T05:22:04.053Z"
}, {
"ecg": 1.04,
"date": "2020-01-21T05:22:05.126Z"
},
]
}
]
}
and i want change convert to array like this :
{
"status": true,
"message": "",
"data": [
[
"2020-01-21T05:22:01.901Z",
null
],
[
"2020-01-21T05:22:01.901Z",
1, 03
]
[
"2020-01-21T05:22:01.901Z",
1.04
]
[
"2020-01-21T05:22:01.901Z",
1.04
]
]
}
i try using map to convert on result like this :
result = result.map((u, i) => [
u.pasien_docs[i].date,
u.pasien_docs[i].ecg,
]);
but why i only get result data of one array not four data ? help me please, thankyou..
{
"status": true,
"message": "",
"data": [
[
"2020-01-21T05:22:01.901Z",
null
]
]
}
Would that work for you?
const src = {"status":true,"message":"","data":[{"pasien_docs":[{"ecg":null,"date":"2020-01-21T05:22:01.901Z"},{"ecg":1.03,"date":"2020-01-21T05:22:02.979Z"},{"ecg":1.04,"date":"2020-01-21T05:22:04.053Z"},{"ecg":1.04,"date":"2020-01-21T05:22:05.126Z"},]}]},
result = {
...src,
data: src.data[0].pasien_docs.map(Object.values)
}
console.log(result)
.as-console-wrapper{min-height:100%;}
If you dont wanna use spread operator, this can also do the trick for you
const source = {"status":true,"message":"","data":[{"pasien_docs":[{"ecg":null,"date":"2020-01-21T05:22:01.901Z"},{"ecg":1.03,"date":"2020-01-21T05:22:02.979Z"},{"ecg":1.04,"date":"2020-01-21T05:22:04.053Z"},{"ecg":1.04,"date":"2020-01-21T05:22:05.126Z"},]}]}
const result = Object.assign({}, source, {
data: source.data[0].pasien_docs.map(Object.values)
})
console.log(result)
let obj = {
status: true,
message: "",
data: [
{
pasien_docs: [
{
ecg: null,
date: "2020-01-21T05:22:01.901Z",
},
{
ecg: 1.03,
date: "2020-01-21T05:22:02.979Z",
},
{
ecg: 1.04,
date: "2020-01-21T05:22:04.053Z",
},
{
ecg: 1.04,
date: "2020-01-21T05:22:05.126Z",
},
],
},
],
};
var finalobj = JSON.parse(JSON.stringify(obj));
var innerobj = obj.data;
var intermd = innerobj.map((data) => {
return data.pasien_docs;
});
finalarray = intermd[0].map((val) => {
return [val.ecg, val.date];
});
console.log(obj);
finalobj.data[0].pasien_docs=finalarray;
console.log(finalobj);
Json:( How to iterate this array of arrays using map function.. I have tried this.. In this.materialList => array i am getting only 1 st array of values 2nd and 3rd array values are getting undefined.. so i am not able to display in html.. )
subrecipes:[
subrecipematerials: [
"id": 1
"material_id": {
"id":1,
"title":"cookies"
}
],
[
"id": 2
material_id: {
"id":2,
"title":"cake"
}
]
subrecipeformulations: [
"id": 1,
"formula_id": {
"id":1,
"title":formula1
}
]
]
subrecipes:[
subrecipematerials: [
"id": 1
material_id: {
"id":1,
"title":"cookies"
}
],
[
"id": 2
material_id: {
"id":2,
"title":"cake"
}
]
subrecipeformulations: [
"id": 1,
"formula_id": {
"id":1,
"title":formula1
}
]
]
component.ts(I have tried this.. In this.materialList => array i am getting only 1 st array of values 2nd and 3rd array values are getting undefined.. so i am not able to display in html.. )
let subrecipeMaterials = this.data.subRecipes.map((item, index) => {
item = item.subrecipeMaterials[index]
return item
})
let tempMatList1 = this.group_By_Data(subrecipeMaterials, "sub_recipe_id")
let matSubrecipies = Object.keys(tempMatList1).map(data => tempMatList1[data])
this.filterMaterials(matSubrecipies)
this.subrecipies = matSubrecipies.map((data, index) => {
return {
matList: this.materialList[index],
formList: this.otherFormulationList[index],
subRec: (index + 1)
}
})
group_By_Data(arr, key) {
return arr.reduce(function (rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
}
filterMaterials(matSubrecipies) {
this.materialList = matSubrecipies.map(sub => {
return sub.filter(mat => {
let checkmat_id = mat.material_id
if (!!checkmat_id) }
return mat.material_id
}
})
})
}
getMaterialListArray(i) {// this function used to display this array through html.. right now only i am getting 1st array..
return this.materialList[i]
}
Your data is not correct. I think it should be in the form:
{subrecipes:[{
subrecipematerials: [{
"id": 1,
"material_id": {
"id":1,
"title":"cookies"
},
},
{
"id": 2,
material_id: {
"id":2,
"title":"cake"
}
}],
subrecipeformulations: [{
"id": 1,
"formula_id": {
"id":1,
"title":"formula1"
}
}]
},
{
subrecipematerials: [{
"id": 1,
material_id: {
"id":1,
"title":"cookies"
}
},
{
"id": 2,
material_id: {
"id":2,
"title":"cake"
}
} ] ,
subrecipeformulations: [{
"id": 1,
"formula_id": {
"id":1,
"title":"formula1"
}
}]
}]
};
Also, the code item = item.subrecipeMaterials[index] should be item = item.subrecipematerials[index] (difference is M and m as it is case sensitive).
Hi have this array:
[ {
"Navn": "Long Island Iced Tea",
"Nummer": "2",
"Glas i ml": "250",
"Instruktioner": "",
"a": "Hæld is i glasset",
"b": "pynt med en skive lime",
"Ingredienser": [
{
"Type": "Spiritus",
"Del1": [
{
"Cointreau": 20
}
],
"Del2": [
{
"Gin": 20
}
],
"Del3": [
{
"Rom_Lys": 20
}
],
"Del4": [
{
"Tequila": 20
}
],
"Del5": [
{
"Vodka": 20
}
]
},
{
"Type": "Vand/Juice",
"Del1": [
{
"Cola": 40
}
],
"Del2": [
{
"Sprite": 20
}
]
},
{
"Type": "Mixer",
"Del1": [
{
"Lime_Sirup": 20
}
]
}
]
}]
Its for a Cocktailmachine.
And i want to filter it by "Del1" searching for (example) "Rom_Lys" & "Cola" & "Vodka", and then output a new array with these specifications.
I tried searching the forums, but can't seem to find something useful. Played around with filter and includes, but cant come up with anything useful.
Thx!
If you want to get items which are contains Cola, then you can use filter and some methods:
const filterWord = 'Cola';
const result = sampleData.filter(s =>
s.Ingredienser.some(s =>
s.Del1.some( e=> e[filterWord])));
console.log(result);
An example:
let sampleData = [
{
"Navn": "Rom & Cola/ Cuba Libre",
"Nummer": "0",
"Glas i ml": "200",
"Instruktioner": "",
"a": "Hæld is i glasset",
"b": "pynt med en skive citron",
"Ingredienser": [
{
"Type": "Spiritus",
"Del1": [
{
"Rom_Lys": 40
}
]
},
{
"Type": "Vand/Juice",
"Del1": [
{
"Cola": 100
}
]
},
{
"Type": "Mixer",
"Del1": [
{}
]
}
]
},
{
"Navn": "Isbjørn",
"Nummer": "1",
"Glas i ml": "200",
"Instruktioner": "",
"a": "Hæld is i glasset",
"b": "pynt med en skive citron",
"Ingredienser": [
{
"Type": "Spiritus",
"Del1": [
{
"Vodka": 30
}
]
},
{
"Type": "Vand/Juice",
"Del1": [
{
"Sprite": 60
}
]
},
{
"Type": "Mixer",
"Del1": [
{
"Blå_Sirup": 30
}
]
}
]
}];
const filterWord = 'Cola';
const result = sampleData.filter(s => s.Ingredienser.some(s => s.Del1.some( e=> e[filterWord])));
console.log(result);
UPDATE:
If you want to check multiple key, then you can use hasOwnProperty method which checks whether the object contains desired key:
const filters = ['Cointreau', 'Gin', 'Rom_Lys'];
const result = sampleData.filter(s =>
s.Ingredienser.some(ingred => {
return Object.keys(ingred).some(k=> {
if (Array.isArray(ingred[k])) {
return ingred[k].some(s=> filters.some(f=> {
return s.hasOwnProperty(f);
}))
}
});
}
));
And the example:
let sampleData = [ {
"Navn": "Long Island Iced Tea",
"Nummer": "2",
"Glas i ml": "250",
"Instruktioner": "",
"a": "Hæld is i glasset",
"b": "pynt med en skive lime",
"Ingredienser": [
{
"Type": "Spiritus",
"Del1": [
{
"Cointreau": 20
}
],
"Del2": [
{
"Gin": 20
}
],
"Del3": [
{
"Rom_Lys": 20
}
],
"Del4": [
{
"Tequila": 20
}
],
"Del5": [
{
"Vodka": 20
}
]
},
{
"Type": "Vand/Juice",
"Del1": [
{
"Cola": 40
}
],
"Del2": [
{
"Sprite": 20
}
]
},
{
"Type": "Mixer",
"Del1": [
{
"Lime_Sirup": 20
}
]
}
]
}];
const filters = ['Cointreau', 'Gin', 'Rom_Lys'];
const result = sampleData.filter(s =>
s.Ingredienser.some(ingred => {
return Object.keys(ingred).some(k=> {
if (Array.isArray(ingred[k])) {
return ingred[k].some(s=> filters.some(f=> {
return s.hasOwnProperty(f);
}))
}
});
}
));
console.log(result);
Try using following code to filter the array.
var filtered = arr.filter(function(unique) {
for (var index = 0; index < unique.Ingredienser.length; index++) {
if (unique.Ingredienser[index].Del1[0].hasOwnProperty(selectedchoice)) {
return true;
}
}
return false;
});