Diskuze: Seřazení pole - rsort() Ale čísla první

PHP PHP Seřazení pole - rsort() Ale čísla první American English version English version

Avatar
Elisse
Člen
Avatar
Elisse:

Zdravím, potřeboval bych prosím poradit, jak už říká titulek.

Příklad:

["5","2","1","D","BC","A"]

Standartní rsort():

["D","BC","A","5","2","1"]

Já potřebuji:

["5","2","1","A","BC","D"]

Nenakopne mě prosím někdo? :)

Editováno 17. října 12:03
 
Odpovědět 17. října 12:02
Avatar
Milan Gallas
Redaktor
Avatar
Odpovídá na Elisse
Milan Gallas:

Ahoj, zkus jako druhý parametr dát - SORT_NUMERIC

 
Nahoru Odpovědět 17. října 12:41
Avatar
Elisse
Člen
Avatar
Odpovídá na Milan Gallas
Elisse:

Už jsem zkoušel to se setřídí úplně "zvláštně"

 
Nahoru Odpovědět 17. října 13:05
Avatar
Jakub Mareš
Člen
Avatar
Jakub Mareš:

Ahoj zkoušel jsem pár věcí, ale ani mně žádná nešla. Už mě napadá snad jen rozdělit pole, potom seřadit obě pole pomocí rsort a sort a potom je zase spojit.

 
Nahoru Odpovědět 17. října 15:23
Avatar
Jakub Mareš
Člen
Avatar
Odpovídá na Jakub Mareš
Jakub Mareš:

Pole rozdělit podle toho jestli to je, nebo není číslo.

 
Nahoru Odpovědět 17. října 15:27
Avatar
Elisse
Člen
Avatar
Odpovídá na Jakub Mareš
Elisse:

Jo to jsme dva napadlo mě to stejné, tak to teda zkusím no :)

 
Nahoru Odpovědět 17. října 15:34
Avatar
Elisse
Člen
Avatar
Odpovídá na Elisse
Elisse:

I když to je šílené, nikdy nevím kolik prvních znaků bude číslo nebo text :-O

 
Nahoru Odpovědět 17. října 15:45
Avatar
Jakub Mareš
Člen
Avatar
Odpovídá na Elisse
Jakub Mareš:

Ahoj použij foreach loop a funkci is_numeric.

 
Nahoru Odpovědět 17. října 16:17
Avatar
Elisse
Člen
Avatar
Odpovídá na Jakub Mareš
Elisse:

Nejspíš jsem špatně popsal zádání stringy jsou ve formátu třeba "115-0226 XMU_China", takže asi nemůžu zkoušet is_numeric :/

 
Nahoru Odpovědět 17. října 16:20
Avatar
Jakub Mareš
Člen
Avatar
Jakub Mareš:

Zkus se podívat jestli není nějáký způsob pomocí regexu, ale s regexem nemám zkušenosti, takže asi už jinak neporadím. Zkusil bych se zeptat na stack exchange, pokud ti tu nikdo jiný nedokáže poradit.

 
Nahoru Odpovědět 17. října 16:29
Avatar
Elisse
Člen
Avatar
Odpovídá na Jakub Mareš
Elisse:

Jo to já fakt taky ne ani nevím o co jde :) Už to řeším na stackoverflow :)

 
Nahoru Odpovědět 17. října 17:03
Avatar
Milan Gallas
Redaktor
Avatar
Odpovídá na Elisse
Milan Gallas:

Tak ono je to těžké, když všechno mícháš dohromady. Ve většině případů stačí použít toto:

$exampleArray2 = ["5","2","1","D","BC","A"];
asort($exampleArray2, SORT_STRING | SORT_FLAG_CASE | SORT_NATURAL);
var_dump($exampleArray2);

echo '<br>';

rnatsort($exampleArray2);

function rnatsort(&$a){
    natsort($a);
    $a = array_reverse($a, true);
    var_dump($a);
}

ale ani jeden z výpisu ti na 100% nevihoví

 
Nahoru Odpovědět 18. října 0:27
Avatar
VelkyBubak
Člen
Avatar
VelkyBubak:

Možná by šlo zápis 115-0226 XMU_China roztrhat na čtyři části, každou vložit jako jedno pole záznamu do DB, pomocí DB setřídit a znovu vypsat do php. Pokud jsou oddělovače vždy první pomlčka, druhý mezera a třetí podtržítko, a zápis je číslo číslo text text, mohlo by to fungovat. Otázkou zůstává, zda to má smysl a zda je přístupná DB.

 
Nahoru Odpovědět 18. října 4:31
Avatar
Elisse
Člen
Avatar
Odpovídá na Milan Gallas
Elisse:

Když ono je to těžké když se před pár lety změnil formát zapisování zakázek, ale vedení je chce pořád mít seřazené :D

 
Nahoru Odpovědět 18. října 8:37
Avatar
Elisse
Člen
Avatar
 
Nahoru Odpovědět 18. října 8:38
Avatar
Elisse
Člen
Avatar
Elisse:

Prozatím jsem se rozhodl pro řešení ve stylu "If is_numeric"

function cmp($a, $b) {
    if ($a == $b) {
        return 0;
    }
    if (is_numeric(substr($a, 0, 1)) && (is_numeric(substr($b, 0, 1)))){
                return ($a < $b) ? 1 : -1;
        }
        if (is_numeric(substr($a, 0, 1)) && (!is_numeric(substr($b, 0, 1)))){
                return -1;
        }
        if (!is_numeric(substr($a, 0, 1)) && (is_numeric(substr($b, 0, 1)))){
                return 1;
        }
        return ($a < $b) ? 1 : -1;
}

uasort($sem, 'cmp');

Nicméně to kontroluje pouze první znak, zatím se to ale zdá dostačující :)

 
Nahoru Odpovědět 18. října 8:51
Avatar
Elisse
Člen
Avatar
Odpovídá na Elisse
Elisse:

Pro toho komu se nechce louskat kód, podmínka spočívá v tom, že pokud je první znak ve stringu číslo, tak je považován automaticky za větší než text

 
Nahoru Odpovědět 18. října 8:56
Avatar
Petr Linhart
Člen
Avatar
Odpovídá na Elisse
Petr Linhart:

A co nějak takhle?
Přetřídí pole obsahující mix formátů '115-0226 XMU_China', 'XMU_China' a '358-1947', tak že třídí první číslem začínající řetězce sestupně a následně písmenné řetězce vzestupně. Pokud je řetězec ve formátu "115-0226 XMU_China" setřídí ho nejprve podle čísla sestupně a při stejných číslech podle písmenné části vzestupně.

Určitě se to dá napsat líp :-)

<?php
/** @var  $a Vstupní pole */
$a = ["115-0226 XMU_China","114-0226 SMU_India","113-0226 KMU_Japan","112-0226 XMU_China","112-0224 XMU_India","112-0224 XMU_China", "XMU_China", "KDS_Korea", "XMU_Japan", "358-1947"];

/**
 * Vytvoří vícenásobné pole
 * @param $array Vstupní pole pro rozdělení řetezců na čísla a písmena
 * @return array
 */
function buildMultiArray($array)
{
    foreach ($array as $key => $value){
        if (preg_match('/^[a-zA-Z]+/', $value)){
            $data[0] = null;
            $data[1] = $value;
        }
        else{
            $data = explode(" ", $value);
        }
        if (empty($data[1])){
            $data[1] = null;
        }
        $nums[] = $data[0];
        $chars[] = $data[1];
    }
    $ar =[$nums, $chars];
    return $ar;
}

/**
 * Sestavení výstupního pole
 * @param $array Vstupní vícenásobné pole pro zjednodušení
 * @return array
 */
function rebuildArray($array)
{
    foreach ($array[0] as $key => $value){
        $ar[] = ltrim(rtrim($value ." ". $array[1][$key], " "), " ");
    }
    return $ar;
}

/**
 * Přetřídí vstupní pole
 * @param $array Vstupní pole pro třídění
 * @return array
 */
function sortArray($array)
{
    $ar = buildMultiArray($array);
    array_multisort($ar[0], SORT_DESC, SORT_NUMERIC,
        $ar[1], SORT_ASC, SORT_STRING);
    $sortedArray = rebuildArray($ar);
    return $sortedArray;
}

echo "Vstupní pole\n";
print_r($a);
echo "\nSetříděné pole\n";
print_r(sortArray($a));

Výstup je následující

Vstupní pole
Array
(
    [0] => 115-0226 XMU_China
    [1] => 114-0226 SMU_India
    [2] => 113-0226 KMU_Japan
    [3] => 112-0226 XMU_China
    [4] => 112-0224 XMU_India
    [5] => 112-0224 XMU_China
    [6] => XMU_China
    [7] => KDS_Korea
    [8] => XMU_Japan
    [9] => 358-1947
)

Setříděné pole
Array
(
    [0] => 358-1947
    [1] => 115-0226 XMU_China
    [2] => 114-0226 SMU_India
    [3] => 113-0226 KMU_Japan
    [4] => 112-0224 XMU_China
    [5] => 112-0226 XMU_China
    [6] => 112-0224 XMU_India
    [7] => KDS_Korea
    [8] => XMU_China
    [9] => XMU_Japan
)
 
Nahoru Odpovědět 18. října 11:04
Avatar
Petr Linhart
Člen
Avatar
Odpovídá na Petr Linhart
Petr Linhart:

už vidím chybku :-D
zapomněl sem tam z pokusů parametr SORT_NUMERIC, ale třídit se to má jako string

 
Nahoru Odpovědět 18. října 11:21
Avatar
Elisse
Člen
Avatar
Odpovídá na Petr Linhart
Elisse:

Hezké :) nicméně už jsem bohužel musel odevzdat řešení když tu todle ještě nebylo, myslím, že formát zakázek se nám hodně dlouho nezmění, tak snad moje řešení bude zatím stačit :D

Použil jsem to o pár komentářů nahoře, kde když string začíná číslem považuje se automaticky za větší než string co nezačíná :)

 
Nahoru Odpovědět 20. října 9:00
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 20 zpráv z 20.