【问题标题】:How to count occurrences in an array of objects by date如何按日期计算对象数组中的出现次数
【发布时间】:2016-04-25 11:58:39
【问题描述】:

我正在使用 TypeScript 或 JavaScript 寻找一个强大的解决方案来计算对象数组中的出现次数。我想在日期之前做到这一点。 (我需要它来创建一些图表)

例如,我有这个数组:

var arr = [
    {date: Wed Jan 20 2016 
        type: "Apples"}, 
    {date: Mon Feb 29 2016
        type: "Peaches"},
    {date: Thu Mar 31 2016 
        type: "Apples"},
    {date: Fri Apr 22 2016 
        type: "Apples"},
    {date: Fri Apr 22 2016 
        type: "Apples"},
    {date: Fri Apr 22 2016 
        type: "Apples"},
    {date: Fri Apr 22 2016 
        type: "Strawberries"}
]

我想要的结果是下一个:

var arr2 = [
        {date: Wed Jan 20 2016 
            type: ["Apples", 1]}, 
        {date: Mon Feb 29 2016
            type: ["Peaches",1]},
        {date: Thu Mar 31 2016 
            type: ["Apples",1]},
        {date: Fri Apr 22 2016 
            type: ["Apples",3],["Strawberries",1]}
    ]

我不知道为什么,但我找不到一个好的解决方案,我正在努力几天......

如果有人知道技巧、函数或其他什么?

【问题讨论】:

  • 显示你已经尝试过的代码。
  • 类似这样的东西:function getOc​​curences(table) { var tableCount = []; table.sort(); var当前=空; var cnt = 0; for (var i = 0; i 0) { tableCount.push([current, cnt]); } 当前 = 表 [i]; cnt = 1; } 其他 {cnt++; } } if (cnt > 0) { tableCount.push([current, cnt]); } 返回表计数; }

标签: javascript arrays json date find-occurrences


【解决方案1】:

试试这个

首先创建一个地图

var map = {}; arr.forEach(function(val){
  map[val.date] = map[val.date] || {};
  map[val.date][val.type] = map[val.date][val.type] || 0;
  map[val.date][val.type]++;
});

现在得到输出

var output = Object.keys(map).map(function(key){
  var tmpArr = [];
  for(var type in map[key])
  {
     tmpArr.push( [ type, map[key][type] ] )
  }
  return { date : key, type: tmpArr  };
})

演示

var arr = [
    {date: "Wed Jan 20 2016",
        type: "Apples"}, 
    {date: "Mon Feb 29 2016",
        type: "Peaches"},
    {date: "Thu Mar 31 2016",
        type: "Apples"},
    {date: "Fri Apr 22 2016" ,
        type: "Apples"},
    {date: "Fri Apr 22 2016" ,
        type: "Apples"},
    {date: "Fri Apr 22 2016" ,
        type: "Apples"},
    {date: "Fri Apr 22 2016" ,
        type: "Strawberries"}
]


    var map = {}; arr.forEach(function(val){
      map[val.date] = map[val.date] || {};
      map[val.date][val.type] = map[val.date][val.type] || 0;
      map[val.date][val.type]++;
    });


    var output = Object.keys(map).map(function(key){
      var tmpArr = [];
      for(var type in map[key])
      {
         tmpArr.push( [ type, map[key][type] ] )
      }
      return { date : key, type: tmpArr  };
    })

    document.body.innerHTML += JSON.stringify(output,0,4);

【讨论】:

  • @Vincent 很高兴为您提供帮助
  • 这对于单排班轮来说非常复杂。与过滤器相比有什么优势?
  • @gurvinder372 过滤器单行在我的回答中。它也只使用一个循环并以更少的操作和更少的临时对象实现相同的目标 - 或者我错过了什么?
  • @Fonzy 是的,它并没有真正使用 OP 数组中的日期。
【解决方案2】:

应该像这样工作:

var x = new Date().getTime(),
    filtered = arr.filter( function (obj) { return obj.date.getTime() >= x }),
    occurenceCount = filtered.length;

我使用 getTime() 将日期转换为整数,因为比较 Date 对象时我有奇怪的行为。 arr2 将包含 x 之后的所有日期(在此示例中为 NOW),并且 count 将返回 arr2 中包含的元素数。

【讨论】:

  • tmp 来自哪里? @Fonzy
【解决方案3】:

使用正确的日期格式(如此处的 ISO 日期和临时对象),您可以使用 Array#forEach 循环并返回所需的结果。它在一个循环中工作。

var array = [{ date: '2016-01-20', type: "Apples" }, { date: '2016-02-29', type: "Peaches" }, { date: '2016-03-31', type: "Apples" }, { date: '2016-04-22', type: "Apples" }, { date: '2016-04-22', type: "Apples" }, { date: '2016-04-22', type: "Apples" }, { date: '2016-04-22', type: "Strawberries" }],
    grouped = [];

array.forEach(function (a) {
    var key = a.date + '|' + a.type;
    if (!this[a.date]) {                
        this[a.date] = { date: a.date, type: [] };;
        grouped.push(this[a.date]);
    }            
    if (!this[key]) {
        this[key] = [a.type, 0];
        this[a.date].type.push(this[key]);
    }
    this[key][1]++;
}, Object.create(null));

document.write('<pre>' + JSON.stringify(grouped, 0, 4) + '</pre>');

【讨论】:

    【解决方案4】:

    过滤数组并检查过滤函数中的日期。

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

    function findItemsByDate(value) {
        // find if an item already exists with the date index
        var dateIndex = arr2.findIndex(findDateIndex);
        // create an array or use the existing one based on result
        if(dateIndex === -1){
          var dateArray = []
        }else{
          dateArray = arr2[dateIndex];
        }
        // find the type object based on the input type and add to it, or create a new one.
        if(dateArray.type.hasOwnProperty(value.type)){
           dateArray.type[value.type] += 1;
        }else{
          dateArray.type[value.type] = 1;
        }
    }
    // utility function to see if an item already exists in the new array with the key for the date.
    function findDateIndex(item, index, arr){
            if(item.date = "Thu Mar 31 2016"){
                alert("Has Data")
            return index;
        }
        return -1;
      }
    

    这将返回一个稍微不同但比您正在寻找的更易于管理的结果。

    var arr2 = [
            {date: "Wed Jan 20 2016", type: ["Apples", 1]}, 
            {date: "Mon Feb 29 2016",type: ["Peaches",1]},
            {date: "Thu Mar 31 2016", type: ["Apples",1]},
            {date: "Fri Apr 22 2016", type: {"Apples":3,"Strawberries":1}}
        ]
    

    【讨论】:

    • 但是如何你会这样做呢?用一个例子来补充你的答案。
    猜你喜欢
    • 1970-01-01
    • 2019-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-24
    • 1970-01-01
    • 2017-09-26
    相关资源
    最近更新 更多