按值减少数组的数组
Reduce an Array of Arrays by value
我有一个类似于下面结构的数组。我正在尝试根据公司名称(例如公司 A)尽可能有效地减少数组。所以基本上,在公司名称相同的情况下,合并内部数组,以便将每个位置的数字添加到相应位置的匹配数组的数字中。此外,如果其中一个数组缺少电子邮件或 phone,请获取具有值的电子邮件或 phone 位置。底部的 resultArray 显示了我想要达到的结果。
*注意 - 我不知道公司后面的数字长度。长度是动态设置的,但每个内部数组的长度将始终相同。所以有时所有的 innerArray 都是 6 个值,其他时候它们的长度可能是 20 个值。
var array = [
[Company A, A-Email, A-Phone, 2, 5, 10],
[Company A, A-Email, , 1, 10, 7],
[Company A, , A-Phone, 3, 2, 4],
[Company B, B-Email, , 1, 10, 7],
[Company B, B-Email, B-Phone, 5, 10, 8],
[Company C, C-Email, C-Phone, 3, 2, 1]
]
var resultArray = [
[Company A, A-Email, A-Phone, 6, 17, 21],
[Company B, B-Email, B-Phone, 6, 20, 15],
[Company C, C-Email, C-Phone, 3, 2, 1]
]
所以最初我正在尝试这样的事情,因为数组已经按公司名称排序:
for (var i = 0; i < array.length - 1; i++) {
var firstArray = array[i]
var nextArray = array[i + 1]
if (nextArray[0] == firstArray[0]) {
for (var t = 3; t <= firstArray.length; t++) {
firstArray[t] = firstArray[t] + nextArray[t]
}
resultArray.push(firstArray);
} else {continue;}
我有大量数据,以这种方式操作确实很繁重,而且我的函数超时,所以我不确定它是否有效。我开始尝试用散列 table 做一个 reduce 方法,但我不太明白。关于如何最有效地执行此操作的任何想法?
而且我不能使用 jQuery,所以请使用纯香草 javascript。
可以使用ES6 reduce
将数组汇总成一个对象。并使用 Object.values
将对象转换为数组。
注意: Fiddle 没有(当前)工作。所以你可能需要在你的浏览器上测试它。
var array=[['Company A','A-Email','A-Phone',2,5,10],['Company A','A-Email',,1,10,7],['Company A',,'A-Phone',3,2,4],['Company B','B-Email',,1,10,7],['Company B','B-Email','B-Phone',5,10,8],['Company C','C-Email','C-Phone',3,2,1]];
var resultArray = Object.values(array.reduce((c, v) => {
c[v[0]] = c[v[0]] || [v[0], null, null].concat(new Array(v.length - 3).fill(0));
c[v[0]][1] = c[v[0]][1] || v[1]; //Update Email
c[v[0]][2] = c[v[0]][2] || v[2]; //Update Phone
//Loop thru the numbers and add
for (var i = 3; i < v.length; i++) c[v[0]][i] += ( v[i] || 0 );
return c;
}, {}));
console.log(resultArray);
哈希表将是正确的方法(假设 'Company A' 等是字符串;否则它是一个映射)。
var companies = {};
for ( var i = 0; i < array.length; i++ ) {
var item = array[ i ];
var name = item[ 0 ];
var phone = item[ 1 ];
var num1 = item[ 2 ];
var num2 = item[ 3 ];
var num3 = item[ 4 ];
if ( companies[ name ] ) {
var record = companies[ name ];
record[ 1 ] = record[ 1 ] || email;
record[ 2 ] = record[ 2 ] || phone;
record[ 2 ] += num1;
record[ 3 ] += num2;
record[ 4 ] += num3;
} else {
companies[ name ] = [ name, email, phone, num1, num2, num3 ]
}
}
var resultArray = Object.values( companies );
您可以试试下面的方法。要点是使用 reduce()
获取充满正确数据的对象,然后使用 Object.values()
.
将其展平回数组
//initial data
var data = [
['Company A', 'A - Email', 'A - Phone', 2, 5, 10],
['Company A', 'A - Email', , 1, 10, 7],
['Company A', , 'A - Phone', 3, 2, 4],
['Company B', 'B - Email', , 1, 10, 7],
['Company B', 'B - Email', 'B - Phone', 5, 10, 8],
['Company C', 'C - Email', 'C - Phone', 3, 2, 1]
];
//reduce function to organize data
var reducer = function(accumulator, currentValue, currentIdx) {
var [companyId, email, phone, i, j, k] = currentValue;
accumulator[companyId] = {
email: !accumulator[companyId] ? email : !accumulator[companyId].email ? email : accumulator[companyId].email,
phone: !accumulator[companyId] ? phone : !accumulator[companyId].phone ? phone : accumulator[companyId].phone,
i: (accumulator[companyId] ? accumulator[companyId].i : 0) + i,
j: (accumulator[companyId] ? accumulator[companyId].j : 0) + j,
k: (accumulator[companyId] ? accumulator[companyId].k : 0) + k
}
return accumulator;
}
var rawData = data.reduce(reducer, {});
//organize data back into array of arrays
var formattedData = [];
for (key in rawData) {
formattedData.push([key].concat(Object.values(rawData[key])));
}
console.log(formattedData);
我有一个类似于下面结构的数组。我正在尝试根据公司名称(例如公司 A)尽可能有效地减少数组。所以基本上,在公司名称相同的情况下,合并内部数组,以便将每个位置的数字添加到相应位置的匹配数组的数字中。此外,如果其中一个数组缺少电子邮件或 phone,请获取具有值的电子邮件或 phone 位置。底部的 resultArray 显示了我想要达到的结果。
*注意 - 我不知道公司后面的数字长度。长度是动态设置的,但每个内部数组的长度将始终相同。所以有时所有的 innerArray 都是 6 个值,其他时候它们的长度可能是 20 个值。
var array = [
[Company A, A-Email, A-Phone, 2, 5, 10],
[Company A, A-Email, , 1, 10, 7],
[Company A, , A-Phone, 3, 2, 4],
[Company B, B-Email, , 1, 10, 7],
[Company B, B-Email, B-Phone, 5, 10, 8],
[Company C, C-Email, C-Phone, 3, 2, 1]
]
var resultArray = [
[Company A, A-Email, A-Phone, 6, 17, 21],
[Company B, B-Email, B-Phone, 6, 20, 15],
[Company C, C-Email, C-Phone, 3, 2, 1]
]
所以最初我正在尝试这样的事情,因为数组已经按公司名称排序:
for (var i = 0; i < array.length - 1; i++) {
var firstArray = array[i]
var nextArray = array[i + 1]
if (nextArray[0] == firstArray[0]) {
for (var t = 3; t <= firstArray.length; t++) {
firstArray[t] = firstArray[t] + nextArray[t]
}
resultArray.push(firstArray);
} else {continue;}
我有大量数据,以这种方式操作确实很繁重,而且我的函数超时,所以我不确定它是否有效。我开始尝试用散列 table 做一个 reduce 方法,但我不太明白。关于如何最有效地执行此操作的任何想法?
而且我不能使用 jQuery,所以请使用纯香草 javascript。
可以使用ES6 reduce
将数组汇总成一个对象。并使用 Object.values
将对象转换为数组。
注意: Fiddle 没有(当前)工作。所以你可能需要在你的浏览器上测试它。
var array=[['Company A','A-Email','A-Phone',2,5,10],['Company A','A-Email',,1,10,7],['Company A',,'A-Phone',3,2,4],['Company B','B-Email',,1,10,7],['Company B','B-Email','B-Phone',5,10,8],['Company C','C-Email','C-Phone',3,2,1]];
var resultArray = Object.values(array.reduce((c, v) => {
c[v[0]] = c[v[0]] || [v[0], null, null].concat(new Array(v.length - 3).fill(0));
c[v[0]][1] = c[v[0]][1] || v[1]; //Update Email
c[v[0]][2] = c[v[0]][2] || v[2]; //Update Phone
//Loop thru the numbers and add
for (var i = 3; i < v.length; i++) c[v[0]][i] += ( v[i] || 0 );
return c;
}, {}));
console.log(resultArray);
哈希表将是正确的方法(假设 'Company A' 等是字符串;否则它是一个映射)。
var companies = {};
for ( var i = 0; i < array.length; i++ ) {
var item = array[ i ];
var name = item[ 0 ];
var phone = item[ 1 ];
var num1 = item[ 2 ];
var num2 = item[ 3 ];
var num3 = item[ 4 ];
if ( companies[ name ] ) {
var record = companies[ name ];
record[ 1 ] = record[ 1 ] || email;
record[ 2 ] = record[ 2 ] || phone;
record[ 2 ] += num1;
record[ 3 ] += num2;
record[ 4 ] += num3;
} else {
companies[ name ] = [ name, email, phone, num1, num2, num3 ]
}
}
var resultArray = Object.values( companies );
您可以试试下面的方法。要点是使用 reduce()
获取充满正确数据的对象,然后使用 Object.values()
.
//initial data
var data = [
['Company A', 'A - Email', 'A - Phone', 2, 5, 10],
['Company A', 'A - Email', , 1, 10, 7],
['Company A', , 'A - Phone', 3, 2, 4],
['Company B', 'B - Email', , 1, 10, 7],
['Company B', 'B - Email', 'B - Phone', 5, 10, 8],
['Company C', 'C - Email', 'C - Phone', 3, 2, 1]
];
//reduce function to organize data
var reducer = function(accumulator, currentValue, currentIdx) {
var [companyId, email, phone, i, j, k] = currentValue;
accumulator[companyId] = {
email: !accumulator[companyId] ? email : !accumulator[companyId].email ? email : accumulator[companyId].email,
phone: !accumulator[companyId] ? phone : !accumulator[companyId].phone ? phone : accumulator[companyId].phone,
i: (accumulator[companyId] ? accumulator[companyId].i : 0) + i,
j: (accumulator[companyId] ? accumulator[companyId].j : 0) + j,
k: (accumulator[companyId] ? accumulator[companyId].k : 0) + k
}
return accumulator;
}
var rawData = data.reduce(reducer, {});
//organize data back into array of arrays
var formattedData = [];
for (key in rawData) {
formattedData.push([key].concat(Object.values(rawData[key])));
}
console.log(formattedData);