I have an orders
array.
orders = [
{table_id: 3, food_id: 5},
{table_id: 4, food_id: 2},
{table_id: 1, food_id: 6},
{table_id: 3, food_id: 4},
{table_id: 4, food_id: 6},
];
I want to write a function to count the number of unique table_id or unique food_id in the array. For eg,
For eg
The list of unique table_id s are1, 3, 4
which totals3
.
The list of unique food_id s are2, 4, 5, 6
which totals4
How do I perform this?
Something like this might work:
function countTableId(orders){
// sets are, well, sets of unique items. no duplicates allowed
let uniqueId = new Set();
for(let ord of orders){
uniqueId.add(ord.table_id);
}
// the size of the set is the number of unique items we added
return uniqueId.size;
}
You could do the same with the food_id property in another function.
@Felix King has a one-line way of doing this, so props to him. It uses the set object and Array.prototype.map()
let unique_table_id_count = new Set(orders.map(x => x.table_id)).size
let unique_food_id_count = new Set(orders.map(x => x.food_id)).size
.map() will loop through the array and look at each table_id, then it will try to add that to the set. The set object will discard an element if it already exists, so we only get unique values. Finally, because of chaining, we can just get the size of the set and we're done!
I'm pretty sure you haven't tried yet because it's as simple as it seems :
var unique_table_ids = [];
var unique_food_ids = [];
for (var i = 0; i < orders.length; i++) {
if (unique_table_ids.indexOf(orders[i].table_id) == -1) // if this Table ID wasn't already in the unique table ID list
unique_table_ids.push(orders[i].table_id); // Add the table ID to the unique table ID list
if (unique_food_ids.indexOf(orders[i].table_id) == -1) // if this Food ID wasn't already in the unique food ID list
unique_food_ids.push(orders[i].food_id); // Add the food ID to the unique food ID list
}
Now, with your current order
array, the respective values of unique_table_ids
and unique_food_ids
are :
unique_table_ids // = [3, 4, 1];
unique_food_ids // = [5, 2, 6, 4];
And of course you can get their length :
unique_table_ids.length // = 3
unique_food_ids.length // = 4
Simply:
var results = {};
orders.forEach(function(item) {
for (var key in item) {
results[key] = results[key] || [];
if (results[key].indexOf(item[key]) == -1)
results[key].push(item[key]);
}
})
for (var key in results) {
console.log("The list of unique "+ key +" are "+ results[key] +" which totals "+ results[key].length);
}
few lines, no new data structures except results object, no edits to your existing code and, most important , no pre-knowledge of orders-objects keys needed
Add the values to a Set and get the size.
If you need a es5 solution then you could implement a set class yourself.
You can create a list of the distinct table and food IDs and count them at the same time. This code will create 2 objects that hold the information...
var orders = [ {table_id: 3, food_id: 5}, {table_id: 4, food_id: 2}, {table_id: 1, food_id: 6}, {table_id: 3, food_id: 4}, {table_id: 4, food_id: 6}, ]; var tables = {}; var foods = {}; for (var i in orders) { var order = orders[i]; var tableId = "table_id_" + order.table_id; var foodId = "food_id_" + order.food_id; if (tables.hasOwnProperty(tableId)) { tables[tableId]++; } else { tables[tableId] = 1; } if (foods.hasOwnProperty(foodId)) { foods[foodId]++; } else { foods[foodId] = 1; } } console.log(tables); console.log(foods);
To anyone else cringing, I apologise for my use of the variable "foods". It's a habit.
You can combine Array.prototype.sort and Array.prototype.filter :
type Order = {
table_id: number;
food_id: number;
}
let orders = [
{table_id: 3, food_id: 5},
{table_id: 4, food_id: 2},
{table_id: 1, food_id: 6},
{table_id: 3, food_id: 4},
{table_id: 4, food_id: 6},
] as Order[];
let uniques = orders.sort((a, b) => a.table_id - b.table_id)
.filter((value, index, array) => index === array.length - 1 || array[index + 1].table_id !== value.table_id);
console.log(uniques.length); // 3
Did it!
orders = [ {table_id: 3, food_id: 5}, {table_id: 4, food_id: 2}, {table_id: 1, food_id: 6}, {table_id: 3, food_id: 4}, {table_id: 4, food_id: 6}, ]; var result=[]; var result2=[]; for(var i=0; i<orders.length; i++){ var current=orders[i]; var ti = current.table_id; var push=true; for(var j=0; j<result.length;j++){ if(ti==result[j]){ push = false; } } if(push){result.push(ti);} var fi = current.food_id; push=true; for(var j=0; j<result2.length;j++){ if(fi==result2[j]){ push = false; } } if(push){result2.push(fi);} } console.log(result + " " + result2); console.log("Unique Tables: " + result.length + " Unique Foods: " + result2.length);
You could use Set
and map the wanted parts.
var orders = [{ table_id: 3, food_id: 5 }, { table_id: 4, food_id: 2 }, { table_id: 1, food_id: 6 }, { table_id: 3, food_id: 4 }, { table_id: 4, food_id: 6 }], getUnique = key => [...new Set(orders.map(o => o[key]))]; console.log(getUnique('table_id')); console.log(getUnique('food_id'));
.as-console-wrapper { max-height: 100% !important; top: 0; }
var orders = [ {table_id: 3, food_id: 5}, {table_id: 4, food_id: 2}, {table_id: 1, food_id: 6}, {table_id: 3, food_id: 4}, {table_id: 4, food_id: 6}, {table_id: 4, food_id: 6}, {table_id: 4, food_id: 6} ]; var tableObj = {}, foodObj = {}; orders.forEach(function(e){ tableObj[e.table_id] = null; foodObj[e.food_id] = null; }); var tableUniqueIDs = Object.keys(tableObj); var foodUniqueIDs = Object.keys(foodObj); console.log("table IDs: ", tableUniqueIDs); console.log("food IDs: ", foodUniqueIDs);
orders = [ {table_id: 3, food_id: 5}, {table_id: 4, food_id: 2}, {table_id: 1, food_id: 6}, {table_id: 3, food_id: 4}, {table_id: 4, food_id: 6}, ]; function count(arr, key) { res = []; arr.map(obj => obj[key]) .filter(n => res.indexOf(n) <= -1 && res.push(n)) return res.length; } console.log(count(orders, 'table_id')); console.log(count(orders, 'food_id'));
PS: kind of hackish with the &&
though...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.