javascript - 根据条件将数组拆分为两个数组
问题描述
我有一张数据表,上面有很多列。我们将此称为 Sheet1 这些列之一具有唯一 ID。
我有另一张数据表。我们称之为 Sheet2。
问:
如果 Sheet1 的所有内容都在一个数组中,而 Sheet2 中 A 列的内容在另一个数组中,我希望能够从 Sheet1 中派生匹配的行并将其放在 Sheet3 上,而那些不匹配的行与 Sheet4 匹配。我希望能够在函数中调用它,因此输入变量应该是sheet1Arr
, sheet1ColNum
(要匹配的列)和sheet2ColArr
. 我希望输出是两个数组。outputWCriteriaArr
和outputWOCriteriaArr
。如果它使事情变得更容易,则可以将输出直接粘贴到函数内的工作表中。我们只需要另外两个输入变量outputWCriteriaSht
和outputWOCriteriaSht
.
使用上面的图像,Sheet3 应该如下所示:
Sheet4 应该是这样的:
其他信息:
- Sheet1 的行数可以超过 10K。已经高达 33K,而且在某些情况下可能会更多。
到目前为止,这是我的尝试。
function splitArrayBasedonCriteria(dataArray,criteriaArray,dataColToMatch,outputWCriteriaSht,outputWOCriteriaSht){
//criteriaArray should be one column
var outputWCriteriaArr = [];
var outputWOCriteriaArr = [];
//Search for strings in specific column and store in array
for (var j in criteriaArray) {
for (var i in dataArray){
//Logger.log(dataArray[i][dataColToMatch - 1])
if (dataArray[i][dataColToMatch - 1].toString().indexOf(criteriaArray[j].toString()) == -1) {
outputWOCriteriaArr.push(dataArray[i])
} else {
outputWCriteriaArr.push(dataArray[i])
}
}
}
Logger.log(outputWCriteriaArr);
Logger.log(outputWOCriteriaArr);
//Output array that met criteria
var destRange = outputWCriteriaSht.getRange(1,1,outputWCriteriaArr.length, outputWCriteriaArr[0].length)
destRange.setNumberFormat("@"); //format cells before pasting values to keep leading zeros.
destRange.setValues(outputWCriteriaArr)
//Output array that did not meet criteria
var destRange = outputWOCriteriaSht.getRange(1,1,outputWOCriteriaArr.length, outputWOCriteriaArr[0].length)
destRange.setNumberFormat("@"); //format cells before pasting values to keep leading zeros.
destRange.setValues(outputWOCriteriaArr)
}
我试图使用 indexOf 在该特定列中查找数据,但我认为这不是dataArray[i][dataColToMatch - 1].toString().indexOf(criteriaArray[j].toString()) == -1
正确的方法。我知道这个函数上的变量名称不同。无论哪种方式都可以。我认为我的解释中的变量对于这篇文章的目的更有意义。
解决方案
流动:
Set
使用第二个数组中的唯一值创建一个arr2
。- 如果第一个数组的
arr1
唯一 ID 匹配集合中的任何内容, - 将其交换到数组的末尾
- 否则,继续下一项。
- 这样,匹配的行被移动到数组的末尾,不匹配的行被保留在顶部
示例脚本:
/**
* @param {object[][]} arr1
* @param {object[][]} arr2
* @param {number} arr1Index Index of arr1 containing unique id
* @param {number} arr2Index Index of arr2 containing unique id
*/
function splitZArr(arr1, arr2, arr1Index, arr2Index) {
const arr2Set = new Set(arr2.map(row => row[arr2Index]));
let end = arr1.length - 1;
for (let start = 0; start <= end; ) {
const uid = arr1[start][arr1Index];
if (arr2Set.has(uid)) {
[arr1[end], arr1[start]] = [arr1[start], arr1[end]];
--end;
} else {
++start;
}
}
return { matched: arr1.splice(++end), unmatched: arr1 };
}
(function test() {
console.info(
splitZArr(
[
[1, 1],
[1, 2],
[1, 3],
[1, 4],
],
[[2], [4]],
1,
0
)
);
})();
推荐阅读
- android - 即使设备被锁定,如何通过服务捕获图像并录制声音?
- php - 无法在php中运行flyway命令
- angular - 如何在 nativescript angular 中创建休息服务
- oracle - SQL Server 2012 Management Studio 提供程序未在 Windows Server 2012 上显示 OraOLEDB.Oracle
- node.js - Electron:每次都无需提示密码即可授予对 sudo 或钥匙串的访问权限
- ruby-on-rails - Rails I18n:使用变量渲染部分
- javascript - 使用 AJAX 的动态下拉菜单
- css - AngularJS Symfony 2 自动生成 CSS
- javascript - CSP 中源“未定义”的脚本是什么意思?
- inkscape - Inkscape:使同一路径的两个段平行或垂直