Porovnání polí a odebrání elementů, které se shodují
- warriotox
- Člen | 30
Snažím se vypsat rezervace v daném terínu. Jako nejsnaží řešení mě
napadlo vytáhnout si z databáze všechny pokoje a jejich postele a udělat
z nich pole, které obsahuje element vždy s ID pokoje na prním místě a
polem s postelemi na druhém místě. Takže pro příklad pokoje ID 1 se
2 postelemi a pokoje ID 2 s 4 postelemi
to pole vypadá takto:
$poleVsechnyPokoje = [[1[1,2]],[2[1,2,3,4]]]
//spravne s PHP by se to zapasalo takhle?
$poleVsechnyPokoje = array(array(1,array(1,2)),array(2,array(1,2,3,4)));
//?
S tímté polem pak tedy srovnávám rezervace které se konají v daném termínu proměněné na pole kde je vždy element s ID rezervovaného pokoje a na druhém pole s rezervovanou postelí. Takže pro příklad rezervace na pokoj 1 v něm postel číslo 2 by vypadala takto:
$poleRezervace = [1[2]]
Tudíž moje otazká je jak porovnat $poleRezervace
s
$poleVsechnyPokoje
a odebrat z něj obsazené postele pro každý
pokoj, tudíž výsledné pole by bylo:
$poleDostupnePokoje [1[1],[2[1,2,3,4]]]
Hádám, že
$poleDostupnePokoje = $poleVsechnyPokoje - $poleReervace
to
nebude… Původně jsem se chtěl zeptat na StackOverflow, ale pak mě napadlo,
že jestli na to má Nette i nějaký helper tak bych rád využil
i toho..
Editoval warriotox (19. 2. 2016 19:43)
- GEpic
- Člen | 566
Když jsme u stackoverflow, zkus toto:
http://stackoverflow.com/…sional-array
Editoval GEpic (19. 2. 2016 20:09)
- Martk
- Člen | 661
Není lepší tohle řešit sql dotazem?
Pravděpodobně hledáš něco jako array diff recursive např. http://php.net/…ray-diff.php#…
Editoval Antik (19. 2. 2016 21:26)
- GEpic
- Člen | 566
Do budoucna z důvodu rozšiřování a udržování dalších informací
ohledně pokojů, jako například cen, vybavení, a podobně bych to také
určitě řešil pomocí databáze a k tomu bych si vytvořil 2 entity –
Room
a Bed
EDIT:
Řešení tvého případu může být následující. Schválně se podívej na
dumps v Tracy, jak vypadá výsledné pole.
Problém polí je ten, že musí mít jak klíč, tak hodnotu, což může být
v tomto případě problém, protože číslo postele (value) 1, má ve
skutečnosti index (klíč /key) 0. Přikládám i jak vypadá
výsledný dump.
$poleVsechnyPokoje = array(
// Pokoj 1 (Key) => Postele (Array)
1 => array (
// Postel (Value)
1, // Bude mít ve finále key / klíč 0 (čili 0 => 1)
2
),
2 => array(
1,
2,
3,
4
)
);
$poleRezervace = array(
1 => array(
2
)
);
// Dump pole před operací
Debugger::barDump($poleVsechnyPokoje);
// foreach (<pole> as <key> => <value>
foreach ($poleRezervace as $pokoj => $postele)
// foreach (keys of <pole> as <key>)
foreach(array_keys($postele) as $postel)
unset($poleVsechnyPokoje[$pokoj][$postel]);
// Dump pole po operaci
Debugger::barDump($poleVsechnyPokoje);
DUMP Před:
array (2)
1 => array (2)
0 => 1
1 => 2
2 => array (4)
0 => 1
1 => 2
2 => 3
3 => 4
DUMP Po:
array (2)
1 => array (1)
1 => 2
2 => array (4)
0 => 1
1 => 2
2 => 3
3 => 4
Dovysvětlení:
$poleVsechnyPokoje[$pokoj][$postel] // Čili $pole[<klic pokoje>][<klic postele>]
// Jenže my určujeme v poli values, né keys, proto:
array_keys($postele)
Editoval GEpic (19. 2. 2016 21:35)
- warriotox
- Člen | 30
GEpic napsal(a):
Řešení tvého případu může být následující. Schválně se podívej na dumps v Tracy, jak vypadá výsledné pole.
Problém polí je ten, že musí mít jak klíč, tak hodnotu, což může být v tomto případě problém, protože číslo postele (value) 1, má ve skutečnosti index (klíč /key) 0. Přikládám i jak vypadá výsledný dump.
V první řadě moc díky za odbsáhlou odpověď, už to čtu asi po 30tý a nemůžu pochopit proč tam ve finále zůstane ta postel #2 a ne ta postel #1. Přece shodné je $poleRezervace[1 ⇒ array (2)] s $poleVsechnyPokoje[1 ⇒ array (2)], tak jaktože pak ve výsledku je tohle?
EDIT: Nebo to je ten problém který popisuješ teda?
EDIT 2: a nemeli by ty pole byt nadefinovany takhle:
//proměnná je pole kde na indexu 0 je pole
$poleVsechnyPokoje = array( 0=>array(
//kde na indexu 0 je hodnota 1 (id pokoje)
0=>1,
//a na indexu 1 je pole
1=>array(
//kde na indexu 0 je hodnota 1 (radove cislo postele)
0=>1,
//kde na indexu 1 je hodnota 2 (dalsi postel..)
1=>2)),
//na indexu 1 je pole... znovu jako vyse
1=>array(
0=>2,
1=>array(
0=>1,
1=>2,
2=>3,
3=>4)));
$poleRezervace = array( 0=>array(
0=>1,
1=>array(0=>2)));
//pro lepsi priklad zamenim ty ciselne hodnoty za text
//proměnná je pole kde na indexu 0 je pole
$poleVsechnyPokoje = array( 0=>array(
//kde na indexu 0 je hodnota 'Luxusni Pokoj' (nazev pokoje)
0=>'Luxusni Pokoj',
//a na indexu 1 je pole
1=>array(
//kde na indexu 0 je hodnota 'xx1' (kod postele)
0=>'xx1',
//kde na indexu 1 je hodnota 'xx2' (kod postele)
1=>'xx2')),
//na indexu 1 je pole... stejny zpusob jako vyse...
1=>array(
0=>'Levny Pokoj',
1=>array(
0=>'zz1',
1=>'zz2',
2=>'zz3',
3=>'zz4')));
$poleRezervace = array( 0=>array(
0=>'Luxusni Pokoj',
1=>array(0=>'xx2')));
\--
Tudiz pak co se shoduje HODNOTA je $poleRezervace[0][1][0] ⇒ 2 ci text
‚xx2‘ s $poleVsechnyPokoje[0][1][1] ⇒ 2 ci text ‚xx2‘. Takze element
na pozici[0][1][1] se Vymaze z $poleVsechnyPokoje a vsechny ostatni zustatnou.
Takze ja pak muzu vypsat vsechny ID pokoju a jednotlivy postele a jenom ta
postel cislo 2 z prvniho pokoje se nevypise, coz je tak jak by to melo
fungovat. Ale ty pises ze vysledek je odstraneni ty postele cislo jedna a
zustane 2ka, furt mi to nejde na rozum
Editoval warriotox (19. 2. 2016 23:44)
- Martk
- Člen | 661
@warriotox Tady je problém, že se klíče nemusí shodovat a ten kód od GEpic předpokládá, že budou stejné (sám to píše v odpovědi).
Tady je kód, který na to nehledí:
foreach ($poleVsechnyPokoje as $klicPokoje => $pole) {
$nalezeno = NULL;
foreach ($poleRezervace as $klic => $poleRez) {
if ($poleRez[0] === $pole[0]) {
$nalezeno = $poleRez[1];
unset($poleRezervace[$klic]); // Již nepotřebujeme, v dalších iteracích se nebude zbytečně prohledávat
break;
}
}
if (!$nalezeno) {
continue;
}
foreach ($pole[1] as $key => $hodnota) {
$klicPostele = array_search($hodnota, $nalezeno);
if ($klicPostele !== FALSE) {
unset($poleVsechnyPokoje[$klicPokoje][1][$key]);
}
}
if (!$poleVsechnyPokoje[$klicPokoje][1]) {
unset($poleVsechnyPokoje[$klicPokoje]);
}
}
Editoval Antik (20. 2. 2016 10:50)
- warriotox
- Člen | 30
Antik napsal(a):
@warriotox Tady je problém, že se klíče nemusí shodovat a ten kód od GEpic předpokládá, že budou stejné (sám to píše v odpovědi).
Tady je kód, který na to nehledí:
Supr díky moc, já sem to ještě než jsem šel spát hodil na StackOverflow ale s tím uspořádáním polí jak jsem navrhoval já, a tam navrhli rešení níže. Každopádně jsem si pak uvědomil, že jsem nebral vůbec v potaz dny o kterých by měli být pokoje a jejich postele volné a napsal sem nový mnohem obsáhlejší post, kde se snažím přijít na to jak to vyřešit už na úrovni databáze, tak jak jsi ostatně sám navrhoval hned v prví odpovědi. Pokud umíš anglicky tak tady je odkaz, jinak zatím moc děkuji za rady, jestli mi to na Stacku někdo pomůže vyřešit tak sem pak doplním řešení.
//reseni pro pripad usporadani poli jak jsem navrhoval v mem komentari z 21:40
foreach ($all as &$room) {
foreach ($reserved as $r) {
if ($room[0] == $r[0]) { // same types of room
foreach ($room[1] as $i => $code) {
if (in_array($code, $r[1])) {
unset($room[1][$i]);
}
}
}
}
$room[1] = array_values($room[1]); // Reset array indexes
}
Editoval warriotox (20. 2. 2016 11:37)
- GEpic
- Člen | 566
warriotox napsal(a):
Antik napsal(a):
@warriotox Tady je problém, že se klíče nemusí shodovat a ten kód od GEpic předpokládá, že budou stejné (sám to píše v odpovědi).
Tady je kód, který na to nehledí:
Supr díky moc, já sem to ještě než jsem šel spát hodil na StackOverflow ale s tím uspořádáním polí jak jsem navrhoval já, a tam navrhli rešení níže. Každopádně jsem si pak uvědomil, že jsem nebral vůbec v potaz dny o kterých by měli být pokoje a jejich postele volné a napsal sem nový mnohem obsáhlejší post, kde se snažím přijít na to jak to vyřešit už na úrovni databáze, tak jak jsi ostatně sám navrhoval hned v prví odpovědi. Pokud umíš anglicky tak tady je odkaz, jinak zatím moc děkuji za rady, jestli mi to na Stacku někdo pomůže vyřešit tak sem pak doplním řešení.
//reseni pro pripad usporadani poli jak jsem navrhoval v mem komentari z 21:40 foreach ($all as &$room) { foreach ($reserved as $r) { if ($room[0] == $r[0]) { // same types of room foreach ($room[1] as $i => $code) { if (in_array($code, $r[1])) { unset($room[1][$i]); } } } } $room[1] = array_values($room[1]); // Reset array indexes }
Pokud můžu poradit, tak toto řeš už na našem fóru. Přeci jen pro práci s databází jsou v Nette šikovné funkce a navrhnuté řešením na StackOverflow si zbytečně zkomplikuješ život.
EDIT: Podobnou aplikaci jsem psal také, univerzálně na jakékoliv možné rezervace, v produkci je zatím upravená verze pro tenisové kurty, můžeš mrknout zde http://scpanamera.cz/ . Kdyby tě něco zajímalo, klidně napiš soukromou zprávu. Bez přihlášení vidíš obsazené rezervace, po přihlášení je informací víc, ale není potřeba.
Editoval GEpic (21. 2. 2016 4:39)