我有一个包含单个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
,但我在这种情况下做了,因为它不那么混乱。如果有人能帮助我,我会非常感激。
答案 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;