以不同的速率循环遍历数组

时间:2014-12-31 02:25:33

标签: javascript arrays for-loop google-apps-script

filesNamed是我想要累积和设置数据的参考数组。因此,对于filesNamed中的每个索引,应该累积来自emailData的包含相同电影标题的数组,并最终设置在Google电子表格中的范围内。将数据设置在一个范围之外,我对此任务的第一部分存在问题。

var filesNamed = [
                  ["Happiness","Karate for Life","Dogtooth","The Streetfighter","Mind Game","The Raid","The Hole","Plaga Zombie","Funny Games"]
                ];

var emailData = [
                      ["Date","Happiness","Sender 1","Receiver 1","Subject 1" ],
                      ["Date","Happiness","Sender 1","Receiver 1","Subject 1" ],
                      ["Date","Happiness","Sender 1","Receiver 1","Subject 1" ],
                      ["Date","Happiness","Sender 1","Receiver 1","Subject 1" ],
                      ["Date","Happiness","Sender 1","Receiver 1","Subject 1" ],
                      ["Date","Karate for Life","Sender 2","Receiver 2","Subject 2" ],
                      ["Date","Karate for Life","Sender 2","Receiver 2","Subject 2" ],
                      ["Date","Karate for Life","Sender 2","Receiver 2","Subject 2" ],
                      ["Date","Karate for Life","Sender 2","Receiver 2","Subject 2" ],
                      ["Date","Karate for Life","Sender 2","Receiver 2","Subject 2" ],
                      ["Date","Karate for Life","Sender 2","Receiver 2","Subject 2" ],
                      ["Date","Dogtooth","Sender 3","Receiver 3","Subject 3" ],
                      ["Date","Dogtooth","Sender 3","Receiver 3","Subject 3" ],
                      ["Date","Dogtooth","Sender 3","Receiver 3","Subject 3" ],
                      ["Date","Dogtooth","Sender 3","Receiver 3","Subject 3" ],
                      ["Date","The Streetfighter","Sender 4","Receiver 4","Subject 4" ],
                      ["Date","The Streetfighter","Sender 4","Receiver 4","Subject 4" ],
                      ["Date","The Streetfighter","Sender 4","Receiver 4","Subject 4" ],
                      ["Date","The Streetfighter","Sender 4","Receiver 4","Subject 4" ],
                      ["Date","Mind Game","Sender 5","Receiver 5","Subject 5" ],
                      ["Date","Mind Game","Sender 5","Receiver 5","Subject 5" ],
                      ["Date","Mind Game","Sender 5","Receiver 5","Subject 5" ],
                      ["Date","Mind Game","Sender 5","Receiver 5","Subject 5" ],
                      ["Date","The Raid","Sender 15","Receiver 15","Subject 15" ],
                      ["Date","The Raid","Sender 15","Receiver 15","Subject 15" ],
                      ["Date","The Raid","Sender 15","Receiver 15","Subject 15" ],
                      ["Date","The Raid","Sender 15","Receiver 15","Subject 15" ],
                      ["Date","The Hole","Sender 25","Receiver 25","Subject 25" ],
                      ["Date","The Hole","Sender 25","Receiver 25","Subject 25" ],
                      ["Date","The Hole","Sender 25","Receiver 25","Subject 25" ],
                      ["Date","Plaga Zombie","Sender 35","Receiver 35","Subject 35" ],
                      ["Date","Plaga Zombie","Sender 35","Receiver 35","Subject 35" ],
                      ["Date","Plaga Zombie","Sender 35","Receiver 35","Subject 35" ],
                      ["Date","Funny Games","Sender 45","Receiver 45","Subject 45" ],
                      ["Date","Funny Games","Sender 45","Receiver 45","Subject 45" ]
                   ];

以下代码的问题在于,虽然第一次循环filesNamed[0][0] == emailData[0][1]会返回一个匹配,但是第二次通过时,两个for循环都会递增 - 但我们还没有完成从{{{ 1}}上面标题为emailData的所有数组(还有4个以上)。我认为计数器应该只在循环中断后递增,表示我们已经到达属于移动幸福的最后一个数组。我尝试将计数器(l ++)放在else语句中,但这不起作用。

就像我可以说明的那样:我希望属于特定电影片目的数组中的所有数据都放在自己的电子表格中。每个子数组(从日期开始)应该在它自己的行上,其中索引将跨越5列。

Happiness

幸福电子表格将包含5行。空手道生活电子表格将包含6行。 Dogtooth电子表格将包含4行。等等......

一位朋友建议我学习迭代器,我会,但我想知道是否有另一种方法来构建我的双循环以获得更接近原始方法的工作方式。还有一些教训可以摆脱这种失败。

2 个答案:

答案 0 :(得分:1)

您想知道电影片名是否匹配。您可以使用indexOf()确定数组是否具有某个元素。

var isItA_Match = filesNamed.indexOf("Happiness");

如果在“filesNamed”数组中的任何位置找到“Happiness”一词,则将索引号分配给变量“isItA_Match”。如果没有匹配,则返回值-1。

此代码不完整或正确,但希望您了解我尝试使用的逻辑:

function theo() {

  Logger.log("emailData.length: " + emailData.length);
  Logger.log("filesNamed[0].length: " + filesNamed[0].length);

  var happinessArray = [];
  var karateArray = [];

  //Create all the arrays for each movie Title
  for(var i=0;i<emailData.length;i++) {

    var elmtToMatch = emailData[i][1];
    var isItA_Match = filesNamed.indexOf(elmtToMatch);

    if (isItA_Match > -1) {
      Logger.log("match");
      //put data into correct Array
      if (matchCorrectArray) {
         happinessArray = data;
      }
    };
  };
};

使用indexOf()检查数组中的每个元素。您不需要遍历每个元素来查找匹配项。这样就可以避免需要循环。

获得具有正确数据的所有数组后,您可以调用另一个函数,然后将数据写入每个相应的电子表格。创建一个将电影名称与电子表格ID匹配的对象。

创建将电影名称与电子表格ID匹配的对象

var objMovieToSheetID = {"Happiness":"48rjdjfoierawj", "Karate for Life":"894ilkdjfhwo"};

创建一个将电影名称与数组名称

匹配的对象
var objMovieToArrayName = {"Happiness":"Hap", "Karate for Life":"Kar"};

调用函数循环打开每个电子表格的过程

function addDataToSheets() {

  //An object that matches the movie title to the spreadsheet ID
  var objMovieToSheetID = {"Happiness":"48rjdjfoierawj", "Karate for Life":"894ilkdjfhwo"};

  var objMovieToArrayName = {"Happiness":"Hap", "Karate for Life":"Kar"};

  //Loop through all the movie titles and add data to each spreadsheet
  for(var i=0; i<objSheetToArrayName.length; i++){

    // The code below opens a spreadsheet using its ID and logs the name for it.
    // Note that the spreadsheet is NOT physically opened on the client side.
    // It is opened on the server only (for modification by the script).

    //get each movie name from the array in sequence by index
    var movieName = filesNamed[i];
    //Retrieve the spreadsheet ID from the object that matches movie name to spreadsheet ID
    var ssID = objSheetToArrayName[movieName];
    var ss = SpreadsheetApp.openById(ssID);
    Logger.log(ss.getName());

    var dataToAppend = emailData[objMovieToArrayName[movieName]];
    // Appends a new row with to the bottom of the
    // spreadsheet containing the values in the array
    sheet.appendRow(dataToAppend);
  };

};

答案 1 :(得分:1)

我认为你正在寻找的最简单的积累可以是这样的。

function theo2() {
  var accumulatedFiles = filesNamed[0].map(
    function (title) {
      var emails = this;
      return {
        title: title,
        emails: emails.filter(
          function (email) {
            var title = this;
            return email[1] == title;
          },
          title
        )
      };
    },
    emailData
  );
}

这会生成一个对象数组,其中第一个索引是filesNamed中的电影标题索引,标题属性是标题,电子邮件属性是该索引中的数组数组是与标题匹配的数组。 / p>

副产品是它只返回标题与原始源列表匹配的电子邮件。如果您希望允许电子邮件回复确定标题累积而根本没有filesNamed数组,那么您可以更加紧凑。

Snapshot of the debugger of the returned object

这将是一个开始,您可以使用它来填充工作表或任何您想要做的事情。

正如Sandy所指出的,上面的函数放弃了循环的使用,而是.map().filter()。循环也有效,但我个人更喜欢语义描述和方法的简洁性。

为了完整性,循环形式可能因此( 猜测什么,这是你已经或多或少的 ):

function theo3() {
  var accumulatedFiles = [],
      filmEmails = [];

  for (var i = 0; i < filesNamed[0].length; i += 1) {    
    filmEmails = [];
    for (var j = 0; j < emailData.length; j += 1) {
      if (emailData[j][1] == filesNamed[0][i]) {
        filmEmails.push(emailData[j]);
      }
    }
    accumulatedFiles.push({title: filesNamed[0][i], emails: filmEmails});
  }
}