I am trying to output the Category property as an array from a nested key/value Javascript object as below.
var data = [{key: "A", values:[{Category:"One", amount:2000},
{Category: "Two", amount:2500},
{Category: "Three", amount: 3000},
{Category: "Four", amount: 3000}]
},
{key: "B", values:[{Category:"One", amount:2000},
{Category: "Two", amount:2500},
{Category: "Three", amount: 3000},
{Category: "Four", amount: 3000}]
},
{key: "C", values:[{Category:"One", amount:2000},
{Category: "Two", amount:2500},
{Category: "Three", amount: 3000},
{Category: "Four", amount: 3000}]
}]
The expected output is as below:-
["One","Two","Three","Four"]
I tried a few ways to achieve this.
The one I got closest to was with a nested map function as below.
data below is a variable containing the Javascript object above.
x = data.map(function(el) {return el.values.map(function(ele,i){return
ele.Category;})})
But the output still is an array of arrays as below. I can slice this and just read one of the arrays returned but I am sure there is a better way of doing this.
[["One","Two","Three","Four"],["One","Two","Three","Four"],
["One","Two","Three","Four"]]
Any suggestions will be greatly appreciated.
4 Answers 4
You could firstly flatten the returned array of arrays and then use Set to remove all duplicated entries.
var data = [{key:"A",values:[{Category:"One",amount:2000},{Category:"Two",amount:2500},{Category:"Three",amount:3000},{Category:"Four",amount:3000}]},{key:"B",values:[{Category:"One",amount:2000},{Category:"Two",amount:2500},{Category:"Three",amount:3000},{Category:"Four",amount:3000}]},{key:"C",values:[{Category:"One",amount:2000},{Category:"Two",amount:2500},{Category:"Three",amount:3000},{Category:"Four",amount:3000}]}],
x = data.map(v => v.values.map(c => c.Category)).reduce((a,b) => a.concat(b)),
res = [...new Set(x)];
console.log(res);
Here's one not-so-cryptic way to do it. Your setup is a little interesting, since there's duplicates, and you appear to want dupes eliminated. An ES6 Set is perfect for that. This gets you the outcome you requested.
let data = [{key:"A",values:[{Category:"One",amount:2000},{Category:"Two",amount:2500},{Category:"Three",amount:3000},{Category:"Four",amount:3000}]},{key:"B",values:[{Category:"One",amount:2000},{Category:"Two",amount:2500},{Category:"Three",amount:3000},{Category:"Four",amount:3000}]},{key:"C",values:[{Category:"One",amount:2000},{Category:"Two",amount:2500},{Category:"Three",amount:3000},{Category:"Four",amount:3000}]}],
set = new Set();
data.forEach(val => {
let v = val.values.forEach ( x => {
set.add(x.Category);
});
});
console.log(Array.from(set));
4 Comments
I use Underscore.js.
var data = [
{
key: "A",
values: [
{Category: "One", amount: 2000},
{Category: "Two", amount: 2500},
{Category: "Three", amount: 3000},
{Category: "Four", amount: 3000}
]
},
...
];
var categories =
_.unique(
_.flatten(
_.map(data, function (item) {
return _.pluck(item.values, 'Category');
})
)
);
Comments
var data = [{key: "A", values:[{Category:"One", amount:2000},
{Category: "Two", amount:2500},
{Category: "Three", amount: 3000},
{Category: "Four", amount: 3000}]
},
{key: "B", values:[{Category:"One", amount:2000},
{Category: "Two", amount:2500},
{Category: "Three", amount: 3000},
{Category: "Four", amount: 3000}]
},
{key: "C", values:[{Category:"One", amount:2000},
{Category: "Two", amount:2500},
{Category: "Three", amount: 3000},
{Category: "Four", amount: 3000}]
}
];
var ans = data.reduce(function(acc, el) {
return acc.concat(el.values.map(x => x.Category));
}, [])
var result = [...new Set(ans)]
console.log(result);
Comments
Explore related questions
See similar questions with these tags.
x = x[0]do?x[0]= [ "One", "Two", "Three", "Four" ]x=x[0]is my only option. But I am trying to see if I can get to the answer in a more efficient way. In a situation where I have a lot of keys. I might be creating a a very large array which I don't really need to.