Home > Net >  Split array in array of arrays based on sum of attribute with google app script
Split array in array of arrays based on sum of attribute with google app script

Time:10-13

I would like to split the following sample array into arrays of array, where the sum of each sub array should not exceed 3 (here var sumMax).

Below is my current codes:

function splitArrByDuration(arr, sumMax) {
  var sumMax = 3;
  var arr = [["a", 2], ["b", 1], ["c", 2], ["d", 1]];
  var splittedArr = [];
  var temp_subArr = [];
  if (arr.length) {
    for (var i = 0; n = arr.length, i < n; i  ) {
      temp_subArr.push(arr[i]);
      if (sumAtIndex(temp_subArr, index = 1) > sumMax && arr.length) {
        var extraRow_temp_subArr = temp_subArr.splice(temp_subArr.length - 1, 1); //remove last element of "temp_subArr" because with it the sum will be greater than "sumMax"
        //Logger.log(extraRow_temp_subArr); 
        arr.unshift(extraRow_temp_subArr[0]); //add the extra from temp_subArr to first index of "arr"
        //i = i - 1;
        splittedArr.push(temp_subArr);
        temp_subArr = [];
      }
    }
  }
  Logger.log(splittedArr);
}

function sumAtIndex(arr, index = 1) {
  var sumIndex = 0;
  if (arr.length) {
    for (var i = 0; n = arr.length, i < n; i  ) {
      sumIndex = sumIndex   arr[i][index];
    }
  }
  //Logger.log(sumIndex);
  return sumIndex;
}

The result from Logger.log(splittedArr) is currently : [[[a, 2.0], [b, 1.0]]]

What is expected should be [[[a, 2.0], [b, 1.0]], [[c, 2.0], [d, 1.0]]]

Can you please help me to get the right result? Thanks in advance,

CodePudding user response:

I thought that when I saw your script, it might be required to process the case that i is the last index. So, when your showing script is modified, how about the following modification?

Modified script:

function splitArrByDuration(arr, sumMax) {
  var sumMax = 3;
  var arr = [["a", 2], ["b", 1], ["c", 2], ["d", 1]];
  var splittedArr = [];
  var temp_subArr = [];
  if (arr.length) {
    for (var i = 0; n = arr.length, i < n; i  ) {
      temp_subArr.push(arr[i]);
      if (sumAtIndex(temp_subArr, index = 1) > sumMax && arr.length) {
        var extraRow_temp_subArr = temp_subArr.splice(temp_subArr.length - 1, 1); //remove last element of "temp_subArr" because with it the sum will be greater than "sumMax"
        //Logger.log(extraRow_temp_subArr); 
        arr.unshift(extraRow_temp_subArr[0]); //add the extra from temp_subArr to first index of "arr"
        //i = i - 1;
        splittedArr.push(temp_subArr);
        temp_subArr = [];

      // Added
      } else if (i == arr.length - 1) {
        splittedArr.push(temp_subArr);
      }

    }
  }
  Logger.log(splittedArr);
}

Added:

From your following comment,

if I change var arr into var arr = [["a", 2], ["b", 1], ["c", 2], ["d", 1], ["e", 4]]; the script never stop to run.

In your script, when the value is ["e", 4], by arr.unshift(extraRow_temp_subArr[0]), arr is continued to be increased. By this, the infinite loop occurs. In order to achieve your new condition by modifying your script, I thought that it is required to add the process for checking the value of each element. The sample modified script is as follows.

Modified script:

function splitArrByDuration(arr, sumMax) {
  var sumMax = 3;
  var arr = [["a", 2], ["b", 1], ["c", 2], ["d", 1], ["e", 4]];
  var splittedArr = [];
  var temp_subArr = [];
  if (arr.length) {
    for (var i = 0; n = arr.length, i < n; i  ) {
      temp_subArr.push(arr[i]);

      // Added
      if (arr[i][1] >= sumMax) {
        var t = temp_subArr.pop();
        splittedArr.push(temp_subArr);
        splittedArr.push([t]);
        temp_subArr = [];

      } else if (sumAtIndex(temp_subArr, index = 1) > sumMax && arr.length) {
        var extraRow_temp_subArr = temp_subArr.splice(temp_subArr.length - 1, 1);
        arr.unshift(extraRow_temp_subArr[0]);
        splittedArr.push(temp_subArr);
        temp_subArr = [];

      // Added
      } else if (i == arr.length - 1) {
        splittedArr.push(temp_subArr);
      }

    }
  }
  Logger.log(splittedArr);
}
  • In this case, [[["a",2],["b",1]],[["c",2],["d",1]],[["e",4]]] is obtained.
  • Related