The most efficient way to detect and remove elements in an array based on the first and last value of the elements

I tried to trim my question, but this is the best I could do. Since I guess it's pretty hard to figure out what I need, I will give an example:

Let's say I have the following array:

$var = array( array(1, 2, 3), array(1, 3), array(1, 2, 4, 3), array(1, 3, 4) ); 

I want to remove all arrays from $var , for which the first and last elements coincide with another array from $var , but have more elements than the last.

So, you should remove the following arrays: (1, 2, 3) and (1, 2, 4, 3) , because they start with 1 and end with 3 and have more elements than (1, 3) , which also starts and ends at 1 and 3 . (1, 3, 4) must remain because there is no other array that starts at 1 and ends at 4 and has fewer elements than it.

I am looking for the most effective way to do this, both in terms of memory and in time. $var can have up to 100 arrays, and each individual array can contain up to 10 elements. I was thinking of using some sort of comparison between all two elements ( for(i=0;...) for(j=i+1;...) complexCompareFunction(); ), but I believe that this is not very efficient.

+6
source share
2 answers

In general, yes, you are too concerned about efficiency (as you are interested in another comment). Although PHP is not the fastest and fastest language, I would suggest creating the simplest solution and only worry about optimizing or optimizing it if there is a noticeable problem with the end result.

This is what I would do, from my head. It is based on the Agrarian answer, but hopefully it will be easier to follow and catch some extreme cases that this answer missed:

 // Assume $var is the array specified in your question function removeRedundantRoutes( $var ){ // This line sorts $var by the length of each route usort( $var, function( $x, $y ){ return count( $x ) - count( $y ); } ); // Create an empty array to store the result in $results = array(); // Check each member of $var foreach( $var as $route ){ $first = $route[0]; $last = $route[ count( $route ) - 1 ]; if( !array_key_exists( "$first-$last", $results ) ){ // If we have not seen a route with this pair of endpoints already, // it must be the shortest such route, so place it in the results array $results[ "$first-$last" ] = $route; } } // Strictly speaking this call to array_values is unnecessary, but // it would eliminate the unusual indexes from the result array return array_values( $results ); } 
+1
source

use current and end

 $all = array(); foreach ($var as $idx=>$arr): $first = current($arr); $last = end($arr); $size = count($arr); $key = $first.'.'.$last; if (isset($all[$key])): if ($size > $all[$key]): unset($var[$idx]); else: $all[$key] = $size; endif; else: $all[$key] = $size; endif; endforeach; 

ops ... you can repeat (again) at the end to provide further deletion of the reduced sized array.

+2
source

Source: https://habr.com/ru/post/909013/


All Articles