Diskuze: Seřazení pole - rsort() Ale čísla první
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Člen
Zobrazeno 20 zpráv z 20.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Ahoj, zkus jako druhý parametr dát - SORT_NUMERIC
Už jsem zkoušel to se setřídí úplně "zvláštně"
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.
Pole rozdělit podle toho jestli to je, nebo není číslo.
Jo to jsme dva napadlo mě to stejné, tak to teda zkusím no
I když to je šílené, nikdy nevím kolik prvních znaků bude číslo nebo text
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 :/
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.
Jo to já fakt taky ne ani nevím o co jde Už to řeším na stackoverflow
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í
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.
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é
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í
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
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
)
už vidím chybku
zapomněl sem tam z pokusů parametr SORT_NUMERIC, ale třídit se to má jako
string
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
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á
Zobrazeno 20 zpráv z 20.