Uspořádání pole – PHP – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Uspořádání pole – PHP – Fórum – Programujte.comUspořádání pole – PHP – Fórum – Programujte.com

 

oxidián0
Grafoman
24. 5. 2016   #1
-
0
-

Mám pole např.

array('birthday', 'regdate', 'editdate');

potřeboval bych to uspořádat podle toho jestli element obsahuje slovo date tak musí být prioritně umístěn doleva. V tomhle případě by mi vyhovovalo spíš sestupné pořadí:

regdate, editdate, birthday

Máte nápad jak to udělat? Nejde jen o to seřadit to sestupně, ale o to aby cokoliv s date bylo prioritně vlevo

Vlastně tam může být více slov co určuje pořadí: date, time, year, datum ....

Nahlásit jako SPAM
IP: 78.45.87.–
q
~ Anonymní uživatel
219 příspěvků
24. 5. 2016   #2
-
0
-

Už jsi dělal nějaké řazení? Vždy je to o porovnávání dvou prvků. Tady řekneš, že to co obsahuje 'date', je menší než to, co ho neobsahuje. Tak to sepiš do funkce a třeba předhoď usortu.

Nahlásit jako SPAM
IP: 78.156.159.–
peter
~ Anonymní uživatel
3981 příspěvků
25. 5. 2016   #3
-
0
-

http://php.net/manual/en/function.sort.php
tam kliknes na link2
http://php.net/….sorting.php
Zajimaji te 'user defined' z te tabulky
http://php.net/…on.usort.php
A jake prekvapeni, je to hned example 1. Kdo by to cekal, ze to najdes v manualu v kapitole o sortovani, ze? :)

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

$a = array(3, 2, 5, 6, 1);

usort($a, "cmp");

Do compare (cmp) funkce si muzes vlozit jakykoliv kod pro porovnani. Ve tvem pripade kod na strpos('date')!==false. Jestlize to bude v $a, tak return-ujes -1, jestlize v $b, pak 1. Jestlize v obou, pak je porovnas $a<$b (viz kod cmp toho prikladu). Jestlize ani jedno, pak take porovnas $a<$b.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:84ce:bd...–
oxidián0
Grafoman
25. 5. 2016   #4
-
0
-

Takto?

public function sortColumnsBySubstring($haystack, $substr){
   if ($haystack == $substr) {
          return 0;
      }
    return strpos($substr) !== false ? -1 : 1; 
 }
 usort($haystack, $this->sortColumnsBySubstring )

Kam mám dát argument $substr? usort má jen dva argumenty

Nechápu jak to mám udělat, $value není nastavené

usort($date_cols, $this->sortColumnsBySubstring($value, 'date') );

V tom příkladu přece nepoužívaj žádné argumenty do funkce cmp:
usort($a, "cmp");

V uzávěře sice argumenty používají tu já ale použít nemohu.

Nahlásit jako SPAM
IP: 78.45.87.–
q
~ Anonymní uživatel
219 příspěvků
25. 5. 2016   #5
-
0
-

Při řazení postupně porovnáváš dvojice prvků a buď je prohodíš nebo ne.

usortu předáváš pole a jméno funkce, kterou se mají prvky porovnávat. Podívej se na ty příklady.

Nahlásit jako SPAM
IP: 78.156.159.–
q
~ Anonymní uživatel
219 příspěvků
25. 5. 2016   #6
-
0
-

   

function cmp($a, $b)
{
	$adate = (strpos($a, 'date') !== false);
	$bdate = (strpos($b, 'date') !== false);
	if (!($adate ^ $bdate)) return strcmp($a, $b); // oba nebo zadny
	return $adate ? -1 : 1; // jeden nebo druhy
}

$a = array('birthday', 'regdate', 'editdate');
usort($a, 'cmp');
Nahlásit jako SPAM
IP: 78.156.159.–
oxidián0
Grafoman
25. 5. 2016   #7
-
0
-

No a co když nechci aby slovo date bylo pevně definované uvnitř funkce? Navíc to je třeba dát do metody protože je to součást třídy.

Nahlásit jako SPAM
IP: 78.45.87.–
peter
~ Anonymní uživatel
3981 příspěvků
25. 5. 2016   #8
-
0
-

Bezva, ted mi to smazalo prispevek, pri kliknuti na zobrazeni noveho :)

Tak misto nazvu funkce tam predas anonymni, kde si definujes, jake slovo chces. Nebo si udelej objekt na cmp, kde pri inicializaci zadas slovo.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:84ce:bd...–
peter
~ Anonymní uživatel
3981 příspěvků
25. 5. 2016   #9
-
0
-

V tom prispevku jsem mel vysvetlene, co ta cmp dela :) Zkusim to znova, strucne, kodem.

function sort(pole, cmp)
{
cyklus cyklus (vsechny polozky pole)
{
// a = pole[i]; b = pole[i+1]
if (cmp(a,b)>0) {tmp=a; a=b; b=tmp;} // zamen a, b
}
}

Klasicke cmp je funkce
cmp (a,b) {return a-b} // nebo kod z example 1

Kdyz tam chces to slovo, tak si to udelej jako objekt, kde se pres this->slovo dostanes k tomu slovu. A nebo tam dej nejakou globalni promenou. A nebo muzes jako anonymni funkci (google, coz te odkaze na manual a usort).
http://php.net/…on.usort.php
Napr "Example 4" nebo prispevek "53 zuallauz at gmail dot com 4 years ago".

Nahlásit jako SPAM
IP: 2001:718:2601:26c:84ce:bd...–
peter
~ Anonymní uživatel
3981 příspěvků
25. 5. 2016   #10
-
0
-

ale jestli to mas z SQL, tak bych to serazoval pres sql.
 

SELECT
  sloupec
  if (sloupec obsahuje 'slovo') ? 1 : 0 AS sloupec_slovo -- ted nevim, jak je tam ta funkce
FROM
  tab
OBDER BY sloupec_slovo DESC, sloupec ASC
Nahlásit jako SPAM
IP: 2001:718:2601:26c:84ce:bd...–
oxidián0
Grafoman
25. 5. 2016   #11
-
0
-

Tak chápu. Takže argumenty se tam nevlezou, musím vše uložit do objektu.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
26. 5. 2016   #12
-
0
-

#6 q 

Smekám před tebou klobouk.

Nyní tedy třeba zavést cyklus

předpokládám že je třeba to upravit takto:

public function sortColumnsBySubstring($a, $b){

$found = false;

foreach ($this->search_date_columns as $k => $needle):

  $asearch = (strpos($a, $needle) !== false);
  $bsearch = (strpos($b, $needle) !== false);   

  if ( $asearch || $bsearch)

    { $found = true; break; }
endforeach;

....

To mi ale nefunguje.

$this->search_date_columns = array('date','datetime','timestamp','time','edited','changed','modified','created','datum'); // needed by sortColumnsBySubstring

$date_cols = array('regdate','time','editdate','createdate','personal','mojedatum','edited','test','modified','changed','pokus','timestamp','hlava');

usort($date_cols, array($this, 'sortColumnsBySubstring' ));


Array
(
    [0] => createdate
    [1] => editdate
    [2] => regdate
    [3] => changed
    [4] => edited
    [5] => hlava
    [6] => modified
    [7] => mojedatum
    [8] => personal
    [9] => pokus
    [10] => test
    [11] => time
    [12] => timestamp
)
 

Kterékoliv ze slov bylo-li by nalezeno, mělo by se řadit doleva

Nahlásit jako SPAM
IP: 78.45.87.–
peter
~ Anonymní uživatel
3981 příspěvků
26. 5. 2016   #13
-
0
-

Prijde mi, ze stale nechapes princip. Postup ma 2 casti. v jedne resis porovnani na slovo a v druhe samotne porovnani retezcu.

cmp (a, b)
je tam slovo?
a ano b ne return -1
a ne b ano return +1
a ano b ano strcmp(a,b)
a ne b ne strcmp(a,b)

return pak resi serazovaci cyklus, jestli polozky prohodi nebo ne a to tak, ze
return>0, pak zamen a,b, cili tmp=a; a=b; b=tmp;

Ale, tvuj kod

public function sortColumnsBySubstring($a, $b){

$found = false; // false = 0, rovnost, neprehazovat

foreach ($this->search_date_columns as $k => $needle):

  $asearch = (strpos($a, $needle) !== false);
  $bsearch = (strpos($b, $needle) !== false);   

  if ( $asearch || $bsearch) 

    { $found = true; break; } // true=1, jako return 1
endforeach;

cili, kdyz bude
a ano b ano, tak udela return 1 a zameni 'a' a 'b', cili poradi ba, OK
a ano b ne, udela return 1, zameni 'a' a 'b', cili poradi ba, SPATNE
a ne, b ano, udela return 1, zameni a a b, poradi ba, OK

Co se ti nezdalo na kodu od Q?

Nahlásit jako SPAM
IP: 2001:718:2601:26c:1980:84...–
Kit+15
Guru
26. 5. 2016   #14
-
+1
-
Zajímavé

#1 oxidián
Dá se to rozhodit do dvou seznamů, seřadit je každý zvlášť a pak je zase slepit.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
26. 5. 2016   #15
-
0
-

#14 Kit
to by bylo nejjednodušší

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
26. 5. 2016   #16
-
0
-

Takhle to stačí

 /** Separate elements to two arrays.
     First array contains elements with date/time strings
     The second array is the rest of elements
  ***/
 private function getDateColumns(&$array)
 {
 $search_date_columns = array('date','datetime','timestamp','time','edited','changed','modified','created','datum');
 $result = array( array(), array() );
 foreach($array as $v1):
  $found = false;
  foreach($search_date_columns as $v2)
    if ( strpos($v1, $v2)!==false )
      { $found = true; break; }
  if ($found)
    $result[0][] = $v1;
  else
    $result[1][] = $v1;
 endforeach;
 return $result;
 }

implementace:

$date_cols = array('regdate','time','editdate','createdate','personal','mojedatum','edited','test','modified','changed','pokus','timestamp','hlava');
$arrays = $this->getDateColumns($date_cols);
rsort($arrays[0]);
$array = array_merge($arrays[0], $arrays[1]); 
unset($arrays);
print_r($array);


Array
(
    [0] => timestamp
    [1] => time
    [2] => regdate
    [3] => mojedatum
    [4] => modified
    [5] => edited
    [6] => editdate
    [7] => createdate
    [8] => changed
    [9] => personal
    [10] => test
    [11] => pokus
    [12] => hlava
)

Nahlásit jako SPAM
IP: 78.45.87.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 14 hostů

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý