使用重复项排序PHP数组

使用重复项排序PHP数组,php,arrays,sorting,Php,Arrays,Sorting,使用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]: Juli

使用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()

编辑:因为我可能没有很好地解释它,所以我想在数组中保留副本。我不想删除重复项。

只需使用即可

结果是:

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

结果是:

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

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

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

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

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;
}
它工作正常,刚刚测试过

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);
        }
    }
}
for($i=0;$i
它工作正常,刚刚测试过

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);
        }
    }
}
for($i=0;$i
请允许我提供一个稍微更加资源友好的解决方案:

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

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

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

使用
array\u shift
array\u intersect
in\u 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\u shift
array\u intersect
in\u 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);

您想删除副本还是保留副本?能否同时发布您当前拥有的代码?复制副本。我不想删除重复的值,只是将它们堆叠在一起。所以实际上,您甚至不需要排序。您正在做的是将第二个和以后的副本移动到第一个找到的值之后的右侧。为什么最后一个副本没有移动?您想删除副本还是保留副本?是否也可以发布您当前拥有的代码?复制它。我不想删除重复的值,只是将它们堆叠在一起。所以实际上,您甚至不需要排序。你正在做的是将第二个和以后的副本移动到第一个找到的值之后的右侧。为什么最后一个Brian被单独留下而没有移动?我起初认为这是一个问题,但这并不完全是OP在寻找的,你是说OP希望这些(从索引4移动的副本值)作为结果的一部分吗?@FredericoSchardong是的!这正是我想要的结果的一部分。我一开始是这么想的,但这并不完全是OP想要的。你是说OP想要这些(从索引4移动的重复值)作为结果的一部分吗?@FredericoSchardong是的!这正是我想要的结果