基于元素的第一个和最后一个值检测和删除数组中元素的最有效方法

时间:2012-02-21 20:15:41

标签: php arrays comparison

我试着缩短我的问题,但这是我能做的最好的。因为我觉得很难理解我需要什么,所以我将提供一个例子:

说我有以下数组:

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

我想要的是从$var中移除所有数组,这些数组的第一个和最后一个元素与$var中的另一个数组相同但元素多于后者。

因此,应删除以下数组:(1, 2, 3)(1, 2, 4, 3),因为它们都以1开头,以3结尾,其元素多于(1, 3) },也以13开头和结尾。 (1, 3, 4)应该保留,因为没有其他数组以1开头,以4结尾,且元素少于它。

我正在寻找最有效的方法,无论是在内存还是时间方面。 $var最多可包含100个数组,每个数组最多可包含10个数组。我想在所有两个元素(for(i=0;...) for(j=i+1;...) complexCompareFunction();)之间进行某种比较,但我认为这不是很有效。

2 个答案:

答案 0 :(得分:2)

使用currentend

$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;

操作...你可以在最后重复(再次)以确保可以进一步删除已经减小的大小的数组

答案 1 :(得分:1)

总的来说,是的,你太担心效率了(正如你在另一条评论中所想的那样)。尽管PHP并不是最快速的语言,但我建议建立最直接的解决方案,并且只有在最终结果存在明显问题时才会担心优化它或简化它。

这就是我要做的事情。它基于ajreal的答案,但希望更容易理解,并抓住一些答案遗漏的边缘案例:

// 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 );
}