PHP关联数组按前一个值排序

问题描述

我正在尝试对以下数组进行排序。该值是键在最终输出数组中应该出现的位置。

$main = array(
    'lorem' => 'lorem','ipsum' => 'duis','sit' => 'adipiscing','duis' => 'sit','amet' => 'elit','consectetur' => 'lorem','adipiscing' => 'consectetur','eiusmod' => 'ipsum','labore' => 'eiusmod','dolore' => 'labore','magna' => 'dolore','incididunt' => 'magna','tempor' => 'incididunt','sed' => 'tempor','elit' => 'sed','aliqua' => 'amet'
);

最终的输出是这样的。

$final = array(
    'lorem' => 'lorem','aliqua' => 'amet'
);

我一直在努力寻找合适的方法,但我似乎把自己带上了错误的道路。我一直只得到一些遵循正确规则的元素。你会如何解决这个问题?我尝试了多种方式循环、拼接和搜索,但都没有成功。

编辑:未清理的尝试

$final = array();

$main = array_merge($current_word_types,$word_types);

foreach ($main as $id => $prevIoUsWord) {
    $final[$id] = $prevIoUsWord;

    if ($id === $prevIoUsWord) {
        continue;
    }

    if (isset($word[$id])) {
        continue;
    }

    $prevIoUsKey = array_search($prevIoUsWord,$main );
    $prevIoUsKeyIndex = array_search($prevIoUsWord,array_keys($main ));

    $final = array_slice($final,$prevIoUsKeyIndex,true) +
                array($prevIoUsKey => $main [$prevIoUsKey]) +
                array_slice($word,NULL,true);
}

编辑 2:这是我从 $main 构建的主列表

// master ordering list
$word_types = array(
    'lorem' => 'lorem','ipsum' => 'lorem','sit' => 'ipsum','amet' => 'duis','consectetur' => 'amet','eiusmod' => 'adipiscing','aliqua' => 'elit'
);

// items that ended up getting special order treatment due 
// someone reordering the words so the $main output to needs 
// to compensate for this. (this Could end up empty at times)
$current_word_types = array(
    'lorem' => 'lorem','duis' => 'consectetur','elit' => 'amet'
);

解决方法

这里有一个函数可以按照你想要的方式对数组进行排序。它基于@deceze 算法(在问题的评论中描述),使用 array_diff 查找不是值的键,然后遍历数组直到该键与该键的值匹配:

function sorter($array) {
    // find the key which doesn't have a matching value
    $unique = array_diff(array_keys($array),$array);
    $key = reset($unique);
    $value = $array[$key];
    $result = array($key => $value);
    // follow the values backwards until the key matches the value
    while ($key != $value) { 
        $key = $array[$key];
        $value = $array[$key];
        $result = array($key => $value) + $result;
    }
    return $result;
}

print_r(sorter($main)) 的数据输出:

Array
(
    [lorem] => lorem
    [consectetur] => lorem
    [adipiscing] => consectetur
    [sit] => adipiscing
    [duis] => sit
    [ipsum] => duis
    [eiusmod] => ipsum
    [labore] => eiusmod
    [dolore] => labore
    [magna] => dolore
    [incididunt] => magna
    [tempor] => incididunt
    [sed] => tempor
    [elit] => sed
    [amet] => elit
    [aliqua] => amet
)

Demo on 3v4l.org