Reputation: 1082
Say I have json that looks like this:
"data": [{
"name": "United States Department of Homeland Security",
"TotalCount": 0,
"UniqueCount": 3,
"AveragedEntry": {
"text": "United States Department of Homeland Security",
"relevance": 0.20341,
},
"WeightedEntry": {
"text": "United States Department of Homeland Security",
"relevance": "NaN",
}
}]
What I want is an json array of objects that looks like:
"data": [{
"name": "United States Department of Homeland Security",
"TotalCount": 0,
"UniqueCount": 3,
"AveragedEntry": 0.20341,
"WeightedEntry": "NaN"
}]
Where the parent properties AveragedEntry and WeightedEntry are assigned the value of the relevance property.
There are a A LOT of questions about how to loop through / create / manipulate a json object but I have not come across this particular problem I want to solve.
Is this possible using javascript/jquery?
I have tried making a deep copy of my initial json and looping through the object and pushing the nested object with no luck. Any help is appreciated thanks.
Upvotes: 0
Views: 2090
Reputation: 26844
Without specifying AveragedEntry
and WeightedEntry
,
You can loop thru the array using map
. Use Object.entries
to convert the object into an array and use reduce
to make a new object.
Check if the value is an object, if it is, use the relevance
property.
let data = [{"name":"United States Department of Homeland Security","TotalCount":0,"UniqueCount":3,"AveragedEntry":{"text":"United States Department of Homeland Security","relevance":0.20341},"WeightedEntry":{"text":"United States Department of Homeland Security","relevance":"NaN"}}];
//Loop each array element using `.map()`
//variable o holds the array elements.
let result = data.map(o => {
//Use `Object.entries()` to convert each array element (object) into an array
//This will return a multi dimensional array with element 0 the key and element 1 the value
//Variable `k` is the key of the object. Like: name, AveragedEntry, WeightedEntry
//Variable `v` is the corresponding value of the key. Like 0 or {"text": "United States Department of Homeland Security","relevance": 0.20341,}
//If the `v` (value) is a type object, use the relevance and assign the value to the accumulator variable `c`
return Object.entries(o).reduce((c, [k, v]) => {
if (typeof v === 'object') c[k] = v.relevance;
else c[k] = v;
return c;
}, {});
});
console.log(result);
Shorter Version: Use Object.assign
to add property and value to an object.
let data = [{"name":"United States Department of Homeland Security","TotalCount":0,"UniqueCount":3,"AveragedEntry":{"text":"United States Department of Homeland Security","relevance":0.20341},"WeightedEntry":{"text":"United States Department of Homeland Security","relevance":"NaN"}}]
let result = data.map(o => Object.entries(o).reduce((c, [k, v]) => Object.assign(c, typeof v === 'object' ? {[k]: v.relevance} : {[k]: v}), {}));
console.log(result);
Upvotes: 1
Reputation: 2547
You can use the Array.map function to create a pipeline for data transforms like this.
let data = [{
"name": "United States Department of Homeland Security",
"TotalCount": 0,
"UniqueCount": 3,
"AveragedEntry": {
"text": "United States Department of Homeland Security",
"relevance": 0.20341,
},
"WeightedEntry": {
"text": "United States Department of Homeland Security",
"relevance": "NaN",
}
}];
// Map the data into the new data structure.
var mapped = data.map(e => ({
name: e.name,
totalCount: e.TotalCount,
uniqueCount: e.UniqueCount,
averagedEntry: e.AveragedEntry.relevance,
weightedEntry: e.WeightedEntry.relevance
}));
console.log(mapped)
This might be a bit more wordy that some of the answers that use the JavaScript meta-programming api, but I think simplicity is best for readability.
Upvotes: 0
Reputation: 30739
You can use Array.map()
to transform the array to desired structure:
var data = [{
"name": "United States Department of Homeland Security",
"TotalCount": 0,
"UniqueCount": 3,
"AveragedEntry": {
"text": "United States Department of Homeland Security",
"relevance": 0.20341,
},
"WeightedEntry": {
"text": "United States Department of Homeland Security",
"relevance": "NaN",
}
}];
var res = data.map((obj)=>{
obj.AveragedEntry = obj.AveragedEntry.relevance;
obj.WeightedEntry = obj.WeightedEntry.relevance;
return obj;
});
console.log(res);
Upvotes: 1
Reputation: 24965
var test = {
"data": [{
"name": "United States Department of Homeland Security",
"TotalCount": 0,
"UniqueCount": 3,
"AveragedEntry": {
"text": "United States Department of Homeland Security",
"relevance": 0.20341,
},
"WeightedEntry": {
"text": "United States Department of Homeland Security",
"relevance": "NaN",
}
}]
};
//make a copy of the object
var newThing = JSON.parse(JSON.stringify(test));
newThing.data.forEach(function(element){
//unnest the values that you want
element.AveragedEntry = element.AveragedEntry.relevance;
element.WeightedEntry = element.WeightedEntry.relevance;
});
//original is not changed
console.log(test);
//new element exists
console.log(newThing);
Upvotes: 2
Reputation: 28455
Use Array.map
let data = [{"name": "United States Department of Homeland Security","TotalCount": 0,"UniqueCount": 3,"AveragedEntry": {"text": "United States Department of Homeland Security","relevance": 0.20341,},"WeightedEntry": {"text": "United States Department of Homeland Security","relevance": "NaN",}}];
data = data.map(({AveragedEntry, WeightedEntry, ...rest}) => Object.assign(rest,{AveragedEntry : AveragedEntry.relevance, WeightedEntry : WeightedEntry.relevance}));
console.log(data);
Upvotes: 1