按第一个元素

时间:2016-01-21 15:47:18

标签: javascript arrays

我有一个包含单个2元素数组的数组,每个数组包含第一个单元格中的日期(以毫秒为单位)和第二个单元格中的数字(事务编号)。它看起来像这样:

var array = [[12135435123, -2],
[12135435123, 1], 
[12135464565, -2], 
[12423675834, 0], 
[12423675834, 1]....];

并非所有ms中的日期在每个单元格中都是相同的,我完全填写了上面的日期,但逻辑是相同的。

我想要做的是在与上面相同的结构中创建另一个数组(全局数组中的2元素数组)。全局数组中的每个元素都是一个2元素数组,表示一组具有相同日期的数组,如下所示:[transactionsCount, netTransaction]

transactionsCount是唯一日期实例的计数,或唯一日期中的事务数。 netTransaction是此组中第二个单元格的总和,或者是日期的净事务的值。

使用上面的例子,我希望最终的数组看起来像这样:

var newArray = [[2, -1], [1,-2],[2,1]...];
// The first array is 2 and -1 because there are 2 transactions for the unique day and the -1 is the net transaction amount. The 2nd array is 1,-2 because there is only 1 transaction for the day with a net total of -2, etc, etc.

我所做的是为我创建一个原始函数,但是我遇到了问题,因为有些情况下函数会超过唯一日期的数量并给出错误的结果。所以我在这里做错了。这就是我所拥有的:

transactions = function transactions(array){
  var transactionCount = 0;
  var netTransactionCounter = 0;
  var finishedArray = [];
  var tempDateArray = [];

  array.forEach(function(item){
    var init = [];
    if(tempDateArray.length == 0){
      tempDateArray.push(item[0]);
      transactionCount++;
      netTransactionCounter += Number(item[1]);
    } else if(tempDateArray.length > 0){
      if(item[0] == tempDateArray[0]){
        transactionCount++;
        netTransactionCounter += Number(item[1]);
      } else if(item[0] !== tempDateArray[0]){
        tempDateArray.pop();
        tempDateArray.push(item[0]);
        init.push(transactionCount);
        init.push(netTransactionCounter);
        finishedArray.push(init);
        transactionCount = 1;
        netTransactionCounter = Number(item[1]);
      }
    }
  });

  return finishedArray;

}

我真的不喜欢使用forEach,但我在这种情况下做了,因为它不那么混乱。如果有人能帮助我,我会非常感激。

2 个答案:

答案 0 :(得分:1)

我很难弄清楚你的逻辑,特别是那个未定义的testing数组。

我会使用字典逻辑来收集日期作为唯一键。此外,它还可以节省管理长度计算的工作量(使用您定义的所有计数器)。

我想说下面的代码是非常自我解释的,但是如果你有理解它,就不要问。

var array = [[12135435123, -2],
[12135435123, 1], 
[12135464565, -2], 
[12423675834, 0], 
[12423675834, 1]];

function transform (array) {
 var dictionary = {};
 for (var i = 0 ; i < array.length ; i++){
   var date = array[i][0].toString();
   var value = array[i][1];

   // add the date to the dictionary if it's not already there
   if ((date in dictionary) === false)
     dictionary[date] = [0, 0];
   // update the count
   dictionary[date][0]++;
   // update the net sum
   dictionary[date][1] += value;      
 }

 // transform dictionary values to array
 var result = [];
 for (var key in dictionary) {
    if (Object.prototype.hasOwnProperty.call(dictionary, key)) {
        var val = dictionary[key];
        result.push(val);
    }
 }
 return result;
}

alert(transform(array));

这里是JSFiddle

答案 1 :(得分:1)

为方便起见,使用es6,但很容易转换为es5:

var array = [[12135435123, -2],
[12135435123, 1], 
[12135464565, -2], 
[12423675834, 0], 
[12423675834, 1]];

//reduce the array into a map, creating objects using the date as keys - with the value being a hash of count and amount;

var map = array.reduce((map, [date, amount]) => {
  if (map[date]) {
    map[date].count = map[date].count + 1;
    map[date].amount = map[date].amount + amount;
  } else {
    map[date] = { count: 1, amount }
  }
  return map;
}, {});

//Map over keys returning tuples of count and amount
var newArray = Object.keys(map).map(key => [map[key].count, map[key].amount]) //gives the result you want;

如果你想更精简并使用更多的解构,你也可以稍微改变一下:

//reduce the array into a map, creating objects using the date as keys - with the value being a hash of count and amount;

var map = array.reduce((map, [date, amount]) => {
  var { count, net } = (map[date] || { count: 0, net : 0 });
  map[date] = { count: count + 1, net: net + amount };
  return map;
}, {});

//Map over keys returning tuples of count and amount
var newArray = Object.keys(map).map(key => [map[key].count, map[key].net]) //gives the result you want;