循环遍历所有数据,创建对象,输出,重复

时间:2018-06-15 11:02:30

标签: javascript object google-apps-script google-sheets

我正在创建一个谷歌脚本,从谷歌工作表中提取事件数据,并在另一张工作表上创建一个事件计划。

数据:事件数据存储在google表格中,其中包含以下列:Event Start, Event End, Event Name, Event Role, Event Worker。工作表中的数据行通常如下所示:6/23/2018 | 6/28/2018 | Holiday Party | Event Manager | Christopher Smith

数据实际上是用来让事件工作者了解他们何时工作以及他们的角色是什么。每个事件都有多个工作人员,因此每个工作人员都有不同的行。

问题:下面的javascript工作得很好;它遍历所有数据,创建事件对象,检查它是否是正确的事件类型,检查事件开始日期并将其与事件计划日期进行比较,然后将数据插入事件计划中的正确位置。 但是,它只针对最后一行数据。我遇到的问题是如何从数据顶部开始,构建第一个事件对象,在计划中插入数据,然后对数据中的下一个事件重复该过程。

//Event object
var event = {
  id: null,
  start: null,
  end: null,
  workers: [],
};

//Loop through data and get event details      
for (var i = 1; i < dataDates.length; i++) {
  if (dataDates[i][3].indexOf("Manager")) {
    event.id = dataDates[i][0] + dataDates[i][2];
    event.start = dataDates[i][0];
    event.end = dataDates[i][1];
  }
}

//Loop through data and group workers together (grouped by specific event)
for (var ii = 1; ii < dataDates.length; ii++) {
  if (dataDates[ii][0] + dataDates[ii][2] == event.id) {
    event.workers.push(dataDates[ii][4]);
  }
}

//Add the event data to the event schedule sheet   
for (var iii = 1; iii < gridDates.length; iii++) {
  if (gridDates[iii][0] == event.start) {
    grid.getRange(iii + 1, 2, 1).setValue(event.workers);
  }
}

2 个答案:

答案 0 :(得分:0)

假设我正确理解你的问题,我认为这里的问题是你只有一个事件对象,你的第一个for循环只是遍历数据中的每一行并不断重新分配id的值,开始并在该事件对象中结束键。在此循环结束时,您有一个对象,其中id,start和end键仅包含数据中最后一行的值。这意味着第2和第3个for循环中的条件语句没有达到预期的效果,因为它们只对仅包含最后一行数据的一个事件对象做出反应。

答案 1 :(得分:0)

没有人可能已经回答这个问题的原因是,你的问题虽然巧妙地制作,却缺乏适当的细节,以便我们以适当的方式帮助你。 例如,您应该包含的是Google表格API返回给您的示例数据结构。

从它看起来,它返回一个2D数组。也许是这样的?

var dataDates = [
  ['6/23/2018', '6/28/2018', 'Holiday Party', 'Event Manager', 'Christopher Smith'],
  ['7/23/2018', '7/28/2018', 'Hawaiian Shirt Day', 'Event Manager', 'John Doe']
];

Keith是对的,因为你只创建了一个事件对象,并且每次循环时都会覆盖该对象。相反,您需要为循环中的每一行创建一个对象。

目前还不清楚为什么你要做这么多循环,为什么你不能在一个循环中实现所有这些,但我会帮助你走上正确的轨道,然后希望我们可以改进这个答案,直到你最终解决它。请记住,我所建议的并不是一种有效的算法,但就像我说的那样,我仍然没有看到你需要做什么。

解决方案的开始: 我们不是创建一个事件对象,而是为初始for循环中的每一次传递创建一个新的事件对象,如下所示:

var dataDates = [
  ['6/23/2018', '6/28/2018', 'Holiday Party', 'Event Manager', 'Christopher Smith'],
  ['7/23/2018', '7/28/2018', 'Hawaiian Shirt Day', 'Event Manager', 'John Doe']
];

// We will store all the dynamically created event objects in this array
var allEvents = [];

// Loop through each row and create an object on the fly, and push it to allEvents
for(var i = 0; i < dataDates.length; i++) {
  var event = {
    id: null,
    start: null,
    end: null,
    workers: []
  };

  if(dataDates[i][3].indexOf('Manager')) {
    event.id = dataDates[i][0] + dataDates[i][2];
    event.start = dataDates[i][0];
    event.end = dataDates[i][1];
  }

  allEvents.push(event);
}

注意我如何在名为allEvents的循环之外创建一个空数组。这将在for循环中存储所有新创建的事件对象。在第一个for循环结束后,让我们执行另一个for循环,迭代遍历allEvents,如下所示:

for(var i = 0; i < allEvents.length; i++) {
   if(dataDates[i][0] + dataDates[i][2] == allEvents[i].id) {
     allEvents[i].workers.push(dataDates[i][4]);
   }
}

这样做,就是更新你的allEvents数组,现在在每个对象中包含正确的worker。

其他评论 同样,我不确定为什么你不能在一个循环中完成以下所有操作,

  • 为包含工作者的每一行创建一个事件对象(不需要第二个循环)
  • 将该事件对象附加到新的Google表格

希望你能对这个答案发表评论并澄清为什么你认为你需要多个循环。

<强> PS 您的第三个for循环引用了一个您没有告诉我们的gridDates数组,或提供它可能包含的内容的详细信息。

请不要亲自接受我的批评,它的目的是帮助您在将来的Stack Overflow上提出更好的问题。

我已经为您提供了一份工作Codepen,以查看我上面提到的一些想法。