2016-01-21 96 views
0

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

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

不在毫秒所有的日期是在每个细胞相同的,我完全由上面的日期,但道理是一样的。

我想要做什么是创建在相同的结构中的另一阵列如上(一个全局数组内-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,但我在这种情况下做,因为它不太凌乱。如果有人能帮助我,我将不胜感激。

回答

1

我有一个很难搞清楚你的​​逻辑,特别是与不确定testing阵列。

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

我会说下面的代码是非常强的自我explainetory,但如果你有了解它出了问题,不hasitate问。

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

+0

对测试部分抱歉。我忘了改变它,因为我在发布之前更改了变量,以便在提问时更有意义。感谢您的回答。我会尽快回复你。 –

+0

你的方法更美观,并且比我上面做的更平滑。感谢您的答复。 –

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;