Reputation: 3301
I have an array of objects as below. I want to sort the array with categories and also find the number of total item in each category. As in below example all category with "toys" should come one after other and it should also be easy to get the count like in below example it is 2(for toys category).
[
{ "category": "toys", "name": "cycle", "itemID": 1594, "price": 1594},
{ "category": "furniture", "name": "chair", "itemID": 15954, "price": 1594},},
{ "category": "furniture", "name": "table", "itemID": 15344, "price": 1594},},
{ "category": "books", "name": "twoLittle", "itemID": 153594, "price": 1594},},
{ "category": "electronic", "name": "Tape", "itemID": 134594, "price": 1594},},
{ "category": "books", "name": "oneLittle", "itemID": 1594436, "price": 1594},},
{ "category": "electronic", "name": "TV", "itemID": 159446, "price": 1594},
{ "category": "toys", "name": "car", "itemID": 1534694, "price": 1594},
]
Any help in right direction would be highly appreciated.
Thanks in advance.
Upvotes: 0
Views: 113
Reputation: 22574
You can use custom sort method using localeCompare
. You can use array#reduce
to get count of each category
.
const data = [{ "category": "toys", "name": "cycle", "itemID": 1594},{ "category": "furniture", "name": "chair", "itemID": 15954},{ "category": "furniture", "name": "table", "itemID": 15344},{ "category": "books", "name": "twoLittle", "itemID": 153594},{ "category": "electronic", "name": "Tape", "itemID": 134594},{ "category": "books", "name": "oneLittle", "itemID": 1594436},{ "category": "electronic", "name": "TV", "itemID": 159446},{ "category": "toys", "name": "car", "itemID": 1534694}];
data.sort((a,b) => a.category.localeCompare(b.category));
console.log(data);
var distinctCount = data.reduce((r,{category}) => {
r[category] = (r[category] || 0) + 1;
return r;
},{})
console.log(distinctCount);
.as-console-wrapper { max-height: 100% !important; top: 0; }
ES 5 Code:
var data = [{ "category": "toys", "name": "cycle", "itemID": 1594 }, { "category": "furniture", "name": "chair", "itemID": 15954 }, { "category": "furniture", "name": "table", "itemID": 15344 }, { "category": "books", "name": "twoLittle", "itemID": 153594 }, { "category": "electronic", "name": "Tape", "itemID": 134594 }, { "category": "books", "name": "oneLittle", "itemID": 1594436 }, { "category": "electronic", "name": "TV", "itemID": 159446 }, { "category": "toys", "name": "car", "itemID": 1534694 }];
data.sort(function (a, b) {
return a.category.localeCompare(b.category);
});
console.log(data);
var distinctCount = data.reduce(function (r, obj) {
var category = obj.category;
r[category] = (r[category] || 0) + 1;
return r;
}, {});
console.log(distinctCount);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 2008
I have broken it down into simple steps.
The end result is an array of the objects including a count property assuming this may need to be used for rendering / templating.
https://jsfiddle.net/wj9m7yz1/
var data = [
{ "category": "toys", "name": "cycle", "itemID": 1594},
{ "category": "furniture", "name": "chair", "itemID": 15954},
{ "category": "furniture", "name": "table", "itemID": 15344},
{ "category": "books", "name": "twoLittle", "itemID": 153594},
{ "category": "electronic", "name": "Tape", "itemID": 134594},
{ "category": "books", "name": "oneLittle", "itemID": 1594436},
{ "category": "electronic", "name": "TV", "itemID": 159446},
{ "category": "toys", "name": "car", "itemID": 1534694}
];
var result={},arr=[], sorted;
// count the totals and keep all your initial data!
for (var i = data.length - 1; i >= 0; i--) {
var item = data[i],
cat = item.category;
result[cat] = result[cat] || {name:item.name, category: cat, count:0};
result[cat].count ++;
}
// pass to an array for sort
for (var o in result){arr.push(result[o])};
// sort on desired prop - in this case count
sorted = arr.sort(function(a,b) {return (a.count > b.count) ? 1 : ((b.count > a.count) ? -1 : 0);} );
console.log(sorted)
Upvotes: 1
Reputation: 787
one liner code and simplest one for you
data = [
{ "category": "toys", "name": "cycle", "itemID": 1594},
{ "category": "furniture", "name": "chair", "itemID": 15954},
{ "category": "furniture", "name": "table", "itemID": 15344},
{ "category": "books", "name": "twoLittle", "itemID": 153594},
{ "category": "electronic", "name": "Tape", "itemID": 134594},
{ "category": "books", "name": "oneLittle", "itemID": 1594436},
{ "category": "electronic", "name": "TV", "itemID": 159446},
{ "category": "toys", "name": "car", "itemID": 1534694}
]
data.sort(function(a, b) {
return (a.category)<(b.category);
});
count = function (ary, classifier) {
classifier = classifier || String;
return ary.reduce(function (counter, item) {
var p = classifier(item);
counter[p] = counter.hasOwnProperty(p) ? counter[p] + 1 : 1;
return counter;
}, {})
};
countByCategory = count(data, function (item) {
return item.category
});
Upvotes: 1
Reputation: 64695
It sounds like what you actually want to do is create an object with the category as the key:
var categories = items.reduce(function(acc, item) {
if (typeof acc[item.category] === 'undefined') {
acc[item.category] = [];
}
acc[item.category].push(item);
return acc;
}, {});
And now you can do:
var num_toys = categories.toys.length; //2
Or if you want to iterate over the toys:
categories.toys.forEach(function(toy) {
console.log(toy.name);
});
Then, you effectively get "sorting" for free (they are grouped by category), you can easily get the number of items in each category (you just check the .length
of the item).
var items = [
{ "category": "toys", "name": "cycle", "itemID": 1594},
{ "category": "furniture", "name": "chair", "itemID": 15954},
{ "category": "furniture", "name": "table", "itemID": 15344},
{ "category": "books", "name": "twoLittle", "itemID": 153594},
{ "category": "electronic", "name": "Tape", "itemID": 134594},
{ "category": "books", "name": "oneLittle", "itemID": 1594436},
{ "category": "electronic", "name": "TV", "itemID": 159446},
{ "category": "toys", "name": "car", "itemID": 1534694}
]
var categories = items.reduce(function(acc, item) {
if (typeof acc[item.category] === 'undefined') {
acc[item.category] = [];
}
acc[item.category].push(item);
return acc;
}, {});
console.log(categories, categories.toys.length);
Upvotes: 1