如何通过对象属性计算对象数组中的唯一元素数?

时间:2017-01-30 14:49:46

标签: javascript typescript ecmascript-6

我有一个orders数组。

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或唯一food_id的数量。例如,

  

例如
  唯一 table_id 的列表为1, 3, 4,总计为3
  唯一 food_id 的列表为2, 4, 5, 6,总计4

我该如何执行此操作?

10 个答案:

答案 0 :(得分:3)

这样的事可能有用:

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;
}

您可以对另一个函数中的food_id属性执行相同的操作。

@Felix King有一个单行的方式做到这一点,所以道具给他。它使用set对象和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()将遍历数组并查看每个table_id,然后它会尝试将其添加到集合中。如果元素已经存在,则set对象将丢弃该元素,因此我们只获取唯一值。最后,由于链接,我们可以获得集合的大小,我们已经完成了!

答案 1 :(得分:3)

我很确定你还没有尝试过,因为它看起来很简单:

1 - 初始化数组

var unique_table_ids = [];
var unique_food_ids = [];

2 - 遍历订单并填充数组

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
}

现在,使用您当前的order数组,unique_table_idsunique_food_ids的相应值为:

unique_table_ids // = [3, 4, 1];
unique_food_ids // = [5, 2, 6, 4];

当然,你可以得到他们的长度:

unique_table_ids.length // = 3
unique_food_ids.length // = 4

答案 2 :(得分:2)

简单地:

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);
}

几行,除了结果对象之外没有新的数据结构,没有对现有代码进行编辑,最重要,不需要预先了解订单 - 对象密钥

答案 3 :(得分:1)

将值添加到Set并获取大小。

如果您需要es5解决方案,那么您可以自己实现一个集合类。

答案 4 :(得分:1)

您可以创建不同的表格和食物ID列表,并同时计算它们。此代码将创建2个包含信息的对象...

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);

对于其他任何人,我为使用变量“食物”而道歉。这是一种习惯。

答案 5 :(得分:1)

您可以合并Array.prototype.sortArray.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

code in playground

答案 6 :(得分:1)

做到了!

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);

答案 7 :(得分:0)

您可以使用Set并映射想要的部分。

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; }

答案 8 :(得分: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);

答案 9 :(得分:0)

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:对&&虽然......

有点迟疑