*/ public static function build( array $snapshots, ?int $end ): array { if ( null !== $end ) { // Strikewise's own records are authoritative from where they start. $snapshots = array_filter( $snapshots, static function ( OmnibusSnapshot $s ) use ( $end ) { return $s->timestamp < $end; } ); } // Stable sort: of several records with the same second, the last one wins. $snapshots = array_values( $snapshots ); $order = array_keys( $snapshots ); usort( $order, static function ( $a, $b ) use ( $snapshots ) { return array( $snapshots[ $a ]->timestamp, $a ) <=> array( $snapshots[ $b ]->timestamp, $b ); } ); // Collapse records of the same second, keeping the last. $by_second = array(); foreach ( $order as $index ) { $by_second[ $snapshots[ $index ]->timestamp ] = $snapshots[ $index ]; } $sorted = array_values( $by_second ); // Merge consecutive records with the same price. $changes = array(); foreach ( $sorted as $snapshot ) { $previous = end( $changes ); if ( false === $previous || ! $previous->same_price_as( $snapshot ) ) { $changes[] = $snapshot; } } $intervals = array(); $count = count( $changes ); foreach ( $changes as $i => $snapshot ) { $to = $i + 1 < $count ? $changes[ $i + 1 ]->timestamp : $end; $intervals[] = array( 'from' => $snapshot->timestamp, 'to' => $to, 'snapshot' => $snapshot, ); } return $intervals; } }