首页 > 解决方案 > 根据条件将数组拆分为两个数组

问题描述

我有一张数据表,上面有很多列。我们将此称为 Sheet1 这些列之一具有唯一 ID。

在此处输入图像描述

我有另一张数据表。我们称之为 Sheet2。

在此处输入图像描述

问: 如果 Sheet1 的所有内容都在一个数组中,而 Sheet2 中 A 列的内容在另一个数组中,我希望能够从 Sheet1 中派生匹配的行并将其放在 Sheet3 上,而那些不匹配的行与 Sheet4 匹配。我希望能够在函数中调用它,因此输入变量应该是sheet1Arr, sheet1ColNum(要匹配的列)和sheet2ColArr. 我希望输出是两个数组。outputWCriteriaArroutputWOCriteriaArr。如果它使事情变得更容易,则可以将输出直接粘贴到函数内的工作表中。我们只需要另外两个输入变量outputWCriteriaShtoutputWOCriteriaSht.

使用上面的图像,Sheet3 应该如下所示:

在此处输入图像描述

Sheet4 应该是这样的:

在此处输入图像描述

其他信息:

到目前为止,这是我的尝试。

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正确的方法。我知道这个函数上的变量名称不同。无论哪种方式都可以。我认为我的解释中的变量对于这篇文章的目的更有意义。

标签: javascriptarraysgoogle-apps-script

解决方案


流动:

  • 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
    )
  );
})();


推荐阅读