亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

PHP重新排序包含重復項目的數組以在重復項目之間保持距離

PHP重新排序包含重復項目的數組以在重復項目之間保持距離

PHP
月關寶盒 2023-11-03 10:55:34
想象一下包含元素的數組 - 零售、零售、娛樂、娛樂我需要對它們進行排序,這樣就不會有重復的元素彼此相鄰,但總體順序可能相當隨機-零售、娛樂、零售、娛樂我已經嘗試過uasort(),但無法退出找到從哪里開始,因為它會比較所有可能的對我想我應該喜歡存儲在外部數組中已經排序檢查的元素以知道在哪種情況下返回 - 或 + integer,并且是可以移動多個位置,即return -2;或者 uasort 回調中的東西輸入數組$input = ['Retail', 'Retail', 'Food', 'Charity', 'Entertainment', 'Entertainment', 'Transport', 'Cosmetics'];輸出數組應該看起來像$output = ['Retail', 'Food', 'Retail', 'Charity', 'Entertainment', 'Transport', 'Entertainment', 'Cosmetics'];我的嘗試:<?php$input  = ['Retail', 'Retail', 'Food', 'Charity', 'Entertainment', 'Entertainment', 'Transport', 'Cosmetics'];$sorted = [];uasort(    $input,    static function ($a, $b) use (&$sorted) {        $is_a_sorted = in_array($a, $sorted, true);        $is_b_sorted = in_array($b, $sorted, true);        switch (true) {            case !$is_a_sorted && !$is_b_sorted:                $sorted[] = $a;                $sorted[] = $b;                return -1;            case $is_a_sorted || $is_b_sorted:                return 1;            default:                return 0;        }    });print_r($input);結果是:Array ( [7] => 化妝品 [4] => 娛樂 [6] => 交通 [5] => 娛樂 [2] => 食品 [3] => 慈善 [0] => 零售 [1] => 零售)
查看完整描述

3 回答

?
蕭十郎

TA貢獻1815條經驗 獲得超13個贊

我決定將數據壓縮為值和計數的關聯數組,然后對數組從出現次數最多的到最少出現的進行排序。我循環遍歷數組并僅處理第一個元素。我將值添加到輸出數組,然后遞減其計數并將其移動到下一個元素之后的位置。

我內置了故障保護功能,以防止在不可能獲得完美結果時出現無限循環。

如果沒有值出現多次,則永遠不會進入循環。

代碼:(演示

function valueSeparator(array $array) {

? ? $maxIterations = count($array);

? ? $counted = array_count_values($array);

? ? arsort($counted);

? ? $iteration = 0;

? ? $result = [];

? ? while (max($counted) > 1 && $iteration < $maxIterations) {

? ? ? ? $count = reset($counted);

? ? ? ? $value = key($counted);

? ? ? ? $result[] = $value;

? ? ? ? unset($counted[$value]);

? ? ? ? arsort($counted);

? ? ? ? if ($count > 1) {

? ? ? ? ? ? $counted = array_merge(

? ? ? ? ? ? ? ? array_splice($counted, 0, 1),

? ? ? ? ? ? ? ? [$value => $count - 1],

? ? ? ? ? ? ? ? $counted

? ? ? ? ? ? );

? ? ? ? }

? ? ? ? ++$iteration;

? ? }

? ? array_push($result, ...array_keys($counted));

? ? var_export($result);

}


foreach ($arrays as $array) {

? ? valueSeparator($array);

? ? echo "\n---\n";

}

測試用例:


$arrays = [

? ? ['Retail', 'Retail', 'Food', 'Food', 'Retail'],

? ? ['Retail', 'Retail', 'Food', 'Charity', 'Entertainment', 'Entertainment', 'Transport', 'Cosmetics'],

? ? ['Food'],

? ? ['Retail', 'Retail', 'Food', 'Retail'],

? ? ['Retail', 'Retail', 'Retail', 'Food', 'Food', 'Food', 'Charity', 'Charity', 'Charity'],

? ? ['Charity', 'Entertainment', 'Retail', 'Retail' ,'Retail']

];

輸出:


array (

? 0 => 'Retail',

? 1 => 'Food',

? 2 => 'Retail',

? 3 => 'Food',

? 4 => 'Retail',

)

---

array (

? 0 => 'Retail',

? 1 => 'Entertainment',

? 2 => 'Food',

? 3 => 'Retail',

? 4 => 'Entertainment',

? 5 => 'Charity',

? 6 => 'Transport',

? 7 => 'Cosmetics',

)

---

array (

? 0 => 'Food',

)

---

array (

? 0 => 'Retail',

? 1 => 'Food',

? 2 => 'Retail',

? 3 => 'Retail',

)

---

array (

? 0 => 'Retail',

? 1 => 'Food',

? 2 => 'Charity',

? 3 => 'Retail',

? 4 => 'Food',

? 5 => 'Charity',

? 6 => 'Retail',

? 7 => 'Food',

? 8 => 'Charity',

)

---

array (

? 0 => 'Retail',

? 1 => 'Charity',

? 2 => 'Retail',

? 3 => 'Entertainment',

? 4 => 'Retail',

)

---


查看完整回答
反對 回復 2023-11-03
?
慕碼人2483693

TA貢獻1860條經驗 獲得超9個贊

我嘗試將排序數組保持在靠近輸入數組的位置。首先,我從數組中刪除任何不適合的元素,然后嘗試稍后插入它們。如果剩下任何元素,我會遍歷數組,將它們插入到任何合適的位置,避免無限循環。結果你得到 2 個數組,一個已排序,另一個找不到合適的位置:


 $input =  ['Charity','Retail','Retail','Retail','Retail', 'Retail' ,'Retail',  'Charity',  'Charity', 'Charity','a' ];


$laRest     = [];

$sorted     = [];

$laNoPlace  = [];


while(count($input) >0) {

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

        if(isset($laRest[$i]) && $laRest[$i] != end($sorted)) {

            $sorted[] = $laRest[$i];

            unset($laRest[$i]);

        }

    }

    $laRest     = array_values($laRest);

    $lsElement  = array_shift($input);

    if (end($sorted) != $lsElement) {

        $sorted[] = $lsElement;

    }

    else {

        $laRest[] = $lsElement;

    }

}


if(count($laRest) >0) {

    while(count($laRest) >0) {

        $lsElement = array_shift($laRest);

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

            if($i != 0 && $sorted[$i] != $lsElement && !isset($sorted[$i+1]) && $lsElement !='') {//end

                array_push($sorted, $lsElement);

                $lsElement = '';

            }

            if($i != 0 && $sorted[$i] != $lsElement && isset($sorted[$i+1]) && $sorted[$i+1] != $lsElement && $lsElement !='') {

                $lsStart = array_slice($sorted, 0, $i+1);

                $lsEnd   = array_slice($sorted , $i+1);

                $sorted  = array_merge($lsStart,  array($lsElement), $lsEnd);

                $lsElement = '';

            } 

            if($i == 0 && $sorted[$i] != $lsElement && $lsElement !='') {//start

              array_unshift($sorted, $lsElement);

              $lsElement = '';

            } 

        }

        if($lsElement != '') {

            $laNoPlace[] = $lsElement;

        }

    }

}


print_r($sorted);

echo "<HR>";

print_r($laNoPlace);

echo "<HR>";


查看完整回答
反對 回復 2023-11-03
?
繁星coding

TA貢獻1797條經驗 獲得超4個贊

我找到了一種排序方法,也許有人有更好的想法:


<?php


$array  = ['Retail', 'Retail', 'Food', 'Charity', 'Entertainment', 'Entertainment', 'Transport', 'Cosmetics'];

$sorted = [];


while (!empty($array)) {

    $current = current($array);


    if (end($sorted) !== $current) {

        $sorted[] = $current;

        array_splice($array, key($array), 1);

    }


    $next = next($array);


    if (!$next) {

        reset($array);

        shuffle($array);

    }

}


print_r($sorted);

輸出:


Array

(

    [0] => Retail

    [1] => Food

    [2] => Charity

    [3] => Entertainment

    [4] => Transport

    [5] => Entertainment

    [6] => Cosmetics

    [7] => Retail

)

另一個輸入示例:


$array  = ['Retail', 'Retail', 'Retail', 'Retail', 'Retail', 'Food', 'Charity', 'Charity', 'Charity', 'Entertainment', 'Entertainment', 'Transport', 'Cosmetics'];

輸出:


Array

(

    [0] => Retail

    [1] => Food

    [2] => Retail

    [3] => Charity

    [4] => Retail

    [5] => Charity

    [6] => Retail

    [7] => Charity

    [8] => Entertainment

    [9] => Transport

    [10] => Entertainment

    [11] => Cosmetics

    [12] => Retail

)

針對特殊場合的更新代碼,例如當輸入是這樣的時,['Retail', 'Retail', 'Food', 'Retail']在我的情況下是合理且可接受的:


<?php


$array  = ['Retail', 'Retail', 'Food', 'Retail'];

$sorted = [];


$tries = 0;

$maxTries = count($array);


while (!empty($array) && $tries <= $maxTries) {

    $current = current($array);


    if (end($sorted) !== $current) {

        $sorted[] = $current;

        array_splice($array, key($array), 1);

    }


    $next = next($array);


    if (!$next) {

        reset($array);

        shuffle($array);

        $tries++;

    }

}


if (!empty($array)) {

    array_push($sorted, ...$array);

}


print_r($sorted);

輸出:


Array

(

    [0] => Retail

    [1] => Food

    [2] => Retail

    [3] => Retail

)


查看完整回答
反對 回復 2023-11-03
  • 3 回答
  • 0 關注
  • 162 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號