对PHP数组进行排序,使重复的值彼此相邻

a7qyws3x  于 2022-12-25  发布在  PHP
关注(0)|答案(6)|浏览(172)

使用PHP我有这个数组:

[0]: John
[1]: Brian
[2]: Julia
[3]: Adam
[4]: Brian
[5]: Jonathan
[6]: Amanda
[7]: Julia
[8]: Nathan

我想对数组进行排序,使其顺序尽可能接近原始顺序,但要堆叠重复项,创建以下数组:

[0]: John
[1]: Brian
[2]: Brian (duplicate value moved from index 4)
[3]: Julia
[4]: Julia (duplicate value moved from index 7)
[5]: Adam
[6]: Jonathan
[7]: Amanda
[8]: Nathan

我假设这是嵌套foreach循环的问题,但我不确定如何在嵌套foreach循环中应用unset()。
编辑:因为我可能没有解释清楚,我想保留数组中的重复项,我不想删除重复项。

nvbavucw

nvbavucw1#

使用array_shiftarray_intersectin_array函数的解决方案:

$arr = [0=> 'John',1=> 'Brian',2=> 'Julia',3=> 'Adam',4=> 'Brian',5=> 'Jonathan',6=> 'Amanda',7=> 'Julia',8=> 'Nathan'];

$size = count($arr);
$i = 0;
$result = [];
while ($i < $size) {
    $el = array_shift($arr);  // current value
    if (!in_array($el, $result)) $result[] = $el;
    $dups = array_intersect($arr, [end($result)]);  // finding duplicates
    if (count($dups)) $result = $result + $dups;    // adding duplicates to "stack" if exist
    $i++;
}

print_r($result);

输出:

Array
(
    [0] => John
    [1] => Brian
    [2] => Brian
    [3] => Julia
    [4] => Julia
    [5] => Adam
    [6] => Jonathan
    [7] => Amanda
    [8] => Nathan
)
w6mmgewl

w6mmgewl2#

不是最有效的解决方案,但有效:

function dupsort(array $input)
{
    $output = array();
    $moved = array();
    foreach ($input as $key => $val)
    {
        if (isset($moved[$key])) {
            continue;
        }

        $moved[$key] = true;
        $output[] = $val;

        foreach ($input as $dupKey => $dupVal) {

            if ($dupVal!==$val) {
                continue;
            }

            if (isset($moved[$dupKey])) {
                continue;
            }

            $moved[$dupKey] = true;
            $output[] = $dupVal;
        }
    }

    return $output;
}
v2g6jxz6

v2g6jxz63#

它工作,只是测试。

for ($i = 0; $i < count($array); $i++) {
    for ($j = $i; $j < count($array); $j++) {

        if ($i < $j && $array[$i] == $array[$j]) {
            $insert = array($array[$j]);
            unset($array[$j]);
            array_splice($array,$i,0,$insert);
        }
    }
}
jutyujz0

jutyujz04#

请允许我提供一个资源友好的解决方案:

function dupsort($data) {
    $result = [];

    foreach($data as $word) {

        // remove all matches of the current word from the source
        $before = count($data);
        $data = array_filter($data, function($x) use ($word) {
            return $x !== $word;
        });

        // add the word to the output as many times as it got removed from source
        $newCount = count($result) + $before - count($data);
        $result = array_pad($result, $newCount, $word);
    }

    return $result;
  }
relj7zay

relj7zay5#

只需使用the sort function

$a = array("a", "b", "c", "a");

sort($a);
var_dump($a);

结果为:

array(4) { [0]=> string(1) "a" [1]=> string(1) "a" [2]=> string(1) "b" [3]=> string(1) "c" }
wfauudbj

wfauudbj6#

只使用一个循环来创建每个唯一值第一次出现的简化查找Map,以及保存每个值最早索引的排序数组。
然后调用array_multisort(),按照排序数组对原始数组进行排序。
不写入迭代函数调用。
代码:(Demo

$order = [];
foreach ($array as $i => $v) {
    $lookup[$v] ??= $i;
    $order[] = $lookup[$v];
}
array_multisort($order, $array);
var_export($array);

相关问题