简体   繁体   English

比较对象数组元素的最佳方法

[英]Best way to compare the elements of an array of objects

So I have an array that consists of some number of objects that have both StartTime and Duration member variables. 因此,我有一个数组,其中包含一些具有StartTime和Duration成员变量的对象。 The startTime variable is a string in the format "14:20" and the Duration variable is a number, representing a number of minutes. startTime变量是格式为“ 14:20”的字符串,Duration变量是数字,表示分钟数。

Can you guys recommend the best logic for going through the array and combining overlapping elements. 你们能推荐遍历数组和组合重叠元素的最佳逻辑吗? For example, if the array had two objects, with the first one having a startTime of "00:00" & duration of 60 and the second object having a startTime of "08:00" & duration of 120 they would be left as separate elements BUT if the second object had a start time of "00:30" and a duration of 120, the two would be combined into one object with a startTime of "00:00" and a duration of 150. 例如,如果数组有两个对象,第一个对象的开始时间为“ 00:00”且持续时间为60,第二个对象的开始时间为“ 08:00”且持续时间为120,则将它们分开放置元素但是如果第二个对象的开始时间为“ 00:30”且持续时间为120,则这两个对象将合并为一个对象,其起始时间为“ 00:00”且持续时间为150。

I have been stuck on the general logic of this for some time, because I can't figure how to handle the case when two blocks are combined, but the new combined block creates a new overlap that must be handled. 一段时间以来,我一直坚持这种通用逻辑,因为当两个块组合在一起时,我无法弄清楚如何处理这种情况,但是新的组合块创建了必须处理的新重叠部分。 Am I just thinking about this wrong?! 我只是在想这个错误吗? Usually I'm good with this sort of thing but am seriously struggling here. 通常我对这种事情很满意,但是在这里我却很努力。

expanding on @gavgrif... 在@gavgrif上扩展...

i recommend something along these lines. 我建议遵循这些方针。

  1. create new array field ['start'] in minutes from midnight (14:20 -> 188) 从午夜(14:20-> 188)在几分钟内创建新的数组字段['start']
  2. sort array by 'start' field 按“开始”字段对数组排序
  3. loop through array looking for overlapping items to merge into segments. 遍历数组以查找重叠项以合并成段。 where overlapping is that start of this new item is not greater than the segment end. 重叠之处在于此新项目的开头不大于段结尾。

php example: php示例:

$segment  = array('start' => -1, 'end' => -1);  // force new segment on init
$segments = array();
foreach ($items as $item) {
    if ($item['start'] > $segment['end']) {

        // add current segment (ignore initial fake segment) to segments
        if ($segment['start'] > -1) {
            // close out current segment
            $segments[] = $segment;                
        }

        // start new segment
        $segment = $item;

    } else {

        // increment segment end if its later than current segment end
        $segment['end'] = max($segment['end'], $item['end'];
    }        
}

// close out final segment
$segments[] = $segment;

I would do this by creating two trees, one indexed by StartTime and the other indexed by EndTime (StartTime + Duration). 我将通过创建两棵树来做到这一点,一棵树由StartTime索引,另一棵树由EndTime(StartTime + Duration)索引。 Search both trees for elements that overlapped. 在两棵树中搜索重叠的元素。 Once the search was complete any found elements would be removed from both trees and the single new element (StartTime = minStartTime(searchResult), EndTime = maxEndTime(searchResult)) would be inserted into both trees. 搜索完成后,将从两棵树中删除所有找到的元素,并将单个新元素(StartTime = minStartTime(searchResult),EndTime = maxEndTime(searchResult))插入两棵树中。

Uses a little extra storage but I believe this makes your overlap problem trivial. 使用了一些额外的存储空间,但是我相信这会使您的重叠问题变得微不足道。

(Tree implementation left as an exercise :) (练习中保留了树的实现:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM