Javascript 将两个$.each()循环重构为一个

Javascript 将两个$.each()循环重构为一个,javascript,jquery,json,Javascript,Jquery,Json,我有一个像这样的JSON对象 { "tasks":[ { "id":"task_3", "taskName":"Task A", "assignee":"Barrack Obama", "timeReqOptimisitic":"4", "timeReqNormal":"8", "timeReqPessimistic":"14", "time

我有一个像这样的JSON对象

{  
   "tasks":[  
      {  
         "id":"task_3",
         "taskName":"Task A",
         "assignee":"Barrack Obama",
         "timeReqOptimisitic":"4",
         "timeReqNormal":"8",
         "timeReqPessimistic":"14",
         "timeUnit":"Days",
         "timeReq":"8.33",
         "positionX":493,
         "positionY":101,
         "lockStatus":"unlocked"
      }
   ],
   "milestones":[  
      {  
         "id":"task_1",
         "milestoneName":"Start",
         "positionX":149,
         "positionY":109,
         "lockStatus":"unlocked",
         "milestoneDate":"2015-04-07"
      },
      {  
         "id":"task_2",
         "milestoneName":"Finish",
         "positionX":989,
         "positionY":367,
         "lockStatus":"unlocked",
         "milestoneDate":"2015-04-22"
      }
   ],
   "connections":[  
      {  
         "connectionId":"con_10",
         "pageSourceId":"task_1",
         "pageTargetId":"task_3"
      },
      {  
         "connectionId":"con_20",
         "pageSourceId":"task_3",
         "pageTargetId":"task_2"
      }
   ]
}
…这是一个最低版本。在实践中,“任务”、“里程碑”和“联系”中有许多项目

我需要遍历对象并确定具有最低/最早“milestoneDate”的“里程碑”项的“id”,然后识别其“pageSourceId”具有相同值的“connections”项并返回其“pageTargetId”

在上面的例子中:

步骤1)迭代对象并确定具有最低/最早“milestoneDate”的“里程碑”项的“id”

回答:millements.id=“task_1”

步骤2)标识“连接”项,该项的“pageSourceId”值相同

回答:connections.pageSourceId=“task_1”

步骤3)返回其“pageTargetId”

回答:“任务3”


我有一个有效的例子。但是,我想知道是否有一种方法可以在不使用非常高的开始日期的情况下完成此操作,并且也可以在一个循环中完成此操作。

由于您没有在这两个循环上解析相同的数组,因此无法合并您的循环

无论如何,您仍然可以删除循环以访问阵列:

也可以对数据进行排序和索引。那么就不需要循环了:

里程碑中的元素应该进行排序,因此最早的里程碑元素应该是里程碑[0]

连接中的元素应通过其pageTargetId属性进行索引,因此请求的元素应为connections[id]

您的两个循环将成为:

var pageTargetId= object.connections[ object.milestones[0].id ].pageTargetId;

正如在评论中所说,排序并不是一个最佳的解决方案,即使这对小集合来说并不重要。 大致上,不需要对所有数据进行排序,只需要最新的数据

作为简单循环的可比替代方案,您可以使用:

这个怎么样:

假设您在第一个循环中获得了
里程碑.id=“task_1”
;在循环之外,我们可以使用jQuery
grep
。由于
connections
将具有唯一的
pageSourceId
,grep将返回一个仅包含一个对象的数组

var filteredData = jQuery.grep('CONNECTIONS_ARRAY', function(element, index){
     return element.pageSourceId == 'MILESTONES_ID'; // Which you get in the loop earlier
});
然后我们可以像这样访问
pageTargetId

if(filteredData.length){    
  filteredData[0].pageTargetId;
}
试一试

var数据={
“任务”:[
{  
“id”:“任务3”,
“任务名称”:“任务A”,
“受让人”:“兵营奥巴马”,
“TimeReqOptimistic”:“4”,
“timeReqNormal”:“8”,
“悲观的”:“14”,
“时间单位”:“天”,
“时间要求”:“8.33”,
“位置X”:493,
“位置”:101,
“锁定状态”:“已解锁”
}
],
“里程碑”:[
{  
“id”:“任务1”,
“milestoneName”:“开始”,
“位置X”:149,
“位置”:109,
“锁定状态”:“已解锁”,
“米司酮酸酯”:“2015-04-07”
},
{  
“id”:“任务2”,
“milestoneName”:“Finish”,
“位置X”:989,
“位置”:367,
“锁定状态”:“已解锁”,
“米司酮酸酯”:“2015-04-22”
}
],
“联系”:[
{  
“连接ID”:“con_10”,
“pageSourceId”:“任务1”,
“pageTargetId”:“任务3”
},
{  
“连接ID”:“con_20”,
“pageSourceId”:“任务3”,
“pageTargetId”:“任务2”
}
]
};
变量日期=[]
,ids=[]
,筛选=$.map(data.millements,函数(值,索引){
push(新日期(value.milestoneDate.getTime());
id.push(value.id);
if(dates.length==数据.里程碑.长度){
var id=ids[$.inArray(Math.min.apply(Math,dates),dates)]
,res=$.grep(data.connections,函数(任务,键){
return task.pageSourceId==id
})[0]。pageTargetId;
返回res
}
})[0]; 
文件。写入(过滤)


是否可以有多个
连接
具有相同的
页面源ID
?否,所有连接都将有一个唯一的页面源ID索引我的连接数组,并且我正在按如下方式排序里程碑数组<代码>对象.里程碑.排序(函数(a,b){return parseDate(a.milestoneDate)-parseDate(b.milestoneDate)})谢谢你的洞察力,它工作得很好。我自己有一个小小的免责声明:排序意味着比顺序解析更多的计算。我更新我的答案。
var filteredData = jQuery.grep('CONNECTIONS_ARRAY', function(element, index){
     return element.pageSourceId == 'MILESTONES_ID'; // Which you get in the loop earlier
});
if(filteredData.length){    
  filteredData[0].pageTargetId;
}
var dates = []
, ids = []
, filtered = $.map(data.milestones, function(value, index) {
    dates.push(new Date(value.milestoneDate).getTime());
    ids.push(value.id);
    if (dates.length === data.milestones.length) {
      var id = ids[$.inArray(Math.min.apply(Math, dates), dates)]
      , res = $.grep(data.connections, function(task, key) {
        return task.pageSourceId === id
      })[0].pageTargetId;
      return res
    }
  })[0]; // `"task_3"`