不同目的地的数组排序算法

时间:2016-05-10 13:17:58

标签: php arrays sorting

我一直试图解决这个问题,但没有运气。

问题是 - 我有一个不同位置的数组。

例如:

   Array
 (
[0] => Array
    (
        [from] => Paris
        [to] => Marseille
    )

[1] => Array
    (
        [from] => Marseille
        [to] => Valencia
    )

[2] => Array
    (
        [from] => Valencia
        [to] => Algiers
    )

[3] => Array
    (
        [from] => Algiers
        [to] => Abu Dhabi
    )

)

无论我给出什么样的顺序,都应该总是返回下一个目的地"来自"它结束的地方。

要排序的数组,以便from键从前一个数组的to键继续。

例如,如果我的位置是"巴黎"和地点"马赛"然后下一个数组顺序应该来自" Marseille"和瓦伦西亚"瓦伦西亚"再次下一个数组应该是"瓦伦西亚"和#34;新地点"。

如果有任何内置功能,我不相信。

4 个答案:

答案 0 :(得分:3)

只要链(或循环)中没有中断,则以下函数应构建已排序的路径:

$from = array_column($route, 'from');
$to = array_column($route, 'to');
$start = array_diff($from, $to);

$sortedRoute = [$route[key($start)]];
$start = $route[key($start)]['to'];
while (true) {
    $key = array_search($start, $from);
    if ($key === false)
        break;
    $sortedRoute[] = $route[$key];
    $start = $route[$key]['to'];
}

Demo

将有更有效的方法来实现这一点,以及基本算法可以优化的方式,例如通过翻转$来使其可以通过键直接访问而不是使用array_search();但作为一个基本的路由器,它的工作原理

答案 1 :(得分:0)

这是一个对多维数组进行排序的函数:

<?php
function sort_travel_plans($a)
{
    $return = [];

    $count_a = count($a);

    while(count($return) !== $count_a)
    {
        foreach($a as $k=>$v)
        {
            $add_where = null;

            if($return)
            {
                foreach($return as $k2=>$v2)
                {
                    if($v['to'] === $v2['from'])
                    {
                        $add_where = 'before';
                    }
                    elseif($v['from'] === $v2['to'])
                    {
                        $add_where = 'after';
                    }
                }
            }
            else
            {
                $add_where = 'after';
            }

            if($add_where === 'before')
            {
                array_unshift($return, $v);
                unset($a[$k]);
            }
            elseif($add_where === 'after')
            {
                $return[] = $v;
                unset($a[$k]);
            }
        }
    }

    unset($a, $add_where, $count_a, $v, $v2);

    return $return;
}

答案 2 :(得分:0)

要记住几个先决条件,

  • 应该给出起点。
  • 不应该有两个分支,但如果用户两次访问同一个地方,则可以附加“&#39; 2&#39;类似的东西。
  • 如果在处理整个数组之前满足死角,那么函数将返回数组,直到它遇到死胡同。或者我们可以只比较输入和输出数组中的元素数量,如果匹配则返回输出,如果不匹配则返回false。

有些事情......

function sortdestinations($input_array, $current_location = null) {
    if (!is_array($input_array) || empty($input_array)) {
        return false;  // empty array or non-array element passed.
    }
    if (!$current_location || empty($current_location)) {
        return false;  // empty start location given
    }
    // Actual beginning of the logic
    $output = array();
    while (count($input_array)) {
        $nextlocation_found = 0;
        foreach ($input_array as $key => $location) {
            if ($location['from'] == $current_location) {
                $output[] = $location; // storing the location
                $current_location = $location['to'];
                unset($input_array[$key]);
                $nextlocation_found = 1;
            }
        }
        if (!$nextlocation_found) {
            return $output;
        }
    }
    return $output;
}

$input_array = array(
    array(
        'from' => 'Paris',
        'to' => 'Marseille'
    ),
    array(
        'from' => 'Marseille',
        'to' => 'Valencia'
    ),
    array(
        'from' => 'Valencia',
        'to' => 'Algiers'
    ),
    array(
        'from' => 'Algiers',
        'to' => 'Abu Dhabi'
    )
);
shuffle($input_array); // randomizing the array each time it is being processed, just for testing. 
echo "<pre>";
print_r($input_array);
echo "</pre>";

$finalout = sortdestinations($input_array, 'Paris');
echo "<pre>";
var_dump($finalout); // var_dump to show even if false is returned :)
echo "</pre>";
die();

<强> DEMO

答案 3 :(得分:0)

嗯,我的解决方案远没有其他人那么优雅,但在这里它仍然是:

function agenda_sort($inArray) {

    // set up sorted array
    $outArray = null;

    //prepare list of cities
    for ($i=0; $i<count($inArray); $i++) {
        $froms[] = $inArray[$i]['from'];
        $tos[] = $inArray[$i]['to'];
    }

    // find the origination city; it should only exist in first array
    $origin = (array_diff($froms, $tos));

    //find origin in first array; push that pair to new array
    for ($i=0; $i<count($inArray); $i++) {
        if ($inArray[$i]['from'] == $origin[0]) {
            $outArray[] = $inArray[$i];
        }

    }


    $c = 0;

    // loop through array and add appropriate city based on to/from comparison
    while (count($outArray) < count($inArray)) {

        for ($i=0; $i<count($inArray); $i++) {
            if ($inArray[$i]['from'] ==$outArray[$c]['to']) {
                $outArray[$i] = $inArray[$c];
            }
        }
    $c++;
    }

    return $outArray;
}