[PHP] array jämförelse beter sig udda

Trädvy Permalänk
Medlem
Plats
Australien
Registrerad
Feb 2002

[PHP] array jämförelse beter sig udda

Hej,
Jag har två arrays, $sort och $antal

$sort = array (1,3,4,5,7,10,11,12); $antal = array (34,56,750,98,23,67,800,54);

Varje post i $sort motsvarar numret på en månad, och varje post i $antal motsvarar ett antal i den månaden.

Vad jag så vill är att de månader som saknas ska skrivas ut, på rätt plats, i samband med ett noll värde.

Min kod hittils som inte funkar som jag vill:

for ($i = 0; $i < 12; $i++) { if ($sort [$i] == $i) { echo $sort [$i]." ". $antal [$i]; } else { echo $i." 0"; } }

Den skriver ut de månader som saknas, fast alla i slutet, och då med loop numret ($i).

Vad gör jag fel?

[edit] fixat $i = 0;

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Sep 2012

Arrayers index börjar på 0. Så när du loopar från 1 till 12 kommer if-satsen bli:
if(sort[1] == 1){
...
}

Vilket ju är falskt, eftersom sort[1] är 3.

För övrigt, varför inte använda en flerdimensionell array?

Trädvy Permalänk
Medlem
Plats
Australien
Registrerad
Feb 2002
Skrivet av Full Strike:

Arrayers index börjar på 0. Så när du loopar från 1 till 12 kommer if-satsen bli:
if(sort[1] == 1){
...
}

Vilket ju är falskt, eftersom sort[1] är 3.

För övrigt, varför inte använda en flerdimensionell array?

Hej,

Vad det gäller index på arrayn så har jag även provat med

$i = 0; $i < 12; $i++;

men utan framgång. Och om det är falskt så bör ju min koden i else-satsen köras, och sedan i nästa loop bör den ju kolla igen. Eller, måste jag nolla $i varje gång (fast då kanske ha $k som loopar upp till 12, för varje gång $i körs)?

När det gäller flerdimensionell array så får jag värderna från en funktion, som returnerar enl

return array($sort, $antal);

Denna funktion vill jag helst inte skriva om då den genererar allt som den ska, och jag har flertalet andra funktioner som förlitar sig på denna retur.

Koden som sådan i min original post _bör_ väl göra det jag vill?

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Aug 2009

<?php $sort = [1,3,4,5,7,10,11,12]; $antal = [34,56,750,98,23,67,800,54]; $arr = []; foreach ($sort as $k => $v) { $arr[$v] = $antal[$k]; } for ($i = 1; $i < 13; $i++) { echo $i . ": "; echo array_key_exists($i, $arr) ? $arr[$i] : 0; echo "<br>"; //radbrytning så det blir enklare att läsa output }

Producerar

1: 34 2: 0 3: 56 4: 750 5: 98 6: 0 7: 23 8: 0 9: 0 10: 67 11: 800 12: 54

7900x @ 4,7ghz - 1080ti @ 2100

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Aug 2009
Skrivet av zajko:

Hej,
Jag har två arrays, $sort och $antal

$sort = array (1,3,4,5,7,10,11,12); $antal = array (34,56,750,98,23,67,800,54);

Varje post i $sort motsvarar numret på en månad, och varje post i $antal motsvarar ett antal i den månaden.

Vad jag så vill är att de månader som saknas ska skrivas ut, på rätt plats, i samband med ett noll värde.

Min kod hittils som inte funkar som jag vill:

for ($i = 0; $i < 12; $i++) { if ($sort [$i] == $i) { echo $sort [$i]." ". $antal [$i]; } else { echo $i." 0"; } }

Den skriver ut de månader som saknas, fast alla i slutet, och då med loop numret ($i).

Vad gör jag fel?

Gör två iterationer "manuellt" så ser vi snabbt vad som är fel.

//sort[0] = 1 if ($sort[0] == 0) do blah else do blah ... //sort[1] = 3 if ($sort[1] == 1) do blah else do blah ...

Så du kollar om 1 = 0 och om 3 = 1, ditt villkor uppfylls aldrig.

7900x @ 4,7ghz - 1080ti @ 2100

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Sep 2012
Skrivet av zajko:

Koden som sådan i min original post _bör_ väl göra det jag vill?

Nej, du kan inte göra så eftersom du ökar på i varje gång. Går att komma runt men skulle inte bli vackert.

Här är snyggaste lösningen jag kan se på rak arm (vet inte riktigt vilken och på vilket format du vill ha datan dock så dumpar bara ut den nu):

<?php $months = range(1, 12); $sort = array (1,3,4,5,7,10,11,12); $antal = array (34,56,750,98,23,67,800,54); $missing = array_values(array_diff($months,$sort)); $existing = array_combine($sort,$antal); echo "<pre>"; echo "<h3>Missing</h3>"; print_r($missing); echo "<h3>Values</h3>"; print_r($existing); echo "</pre>"; ?>

I $missing är då värdena månaderna som saknas. I $existing är nyckeln månaden och värdet antalet för den månaden.

Edit:
För att skriva ut det på samma sätt som du gjorde:

foreach($months as $month){ if(!in_array($month, $missing)){ echo "$month: {$existing[$month]} <br>"; }else{ echo "$month: 0 (missing) <br>"; } }

Trädvy Permalänk
Medlem
Plats
Australien
Registrerad
Feb 2002
Skrivet av celoz:

<?php $sort = [1,3,4,5,7,10,11,12]; $antal = [34,56,750,98,23,67,800,54]; $arr = []; foreach ($sort as $k => $v) { $arr[$v] = $antal[$k]; } for ($i = 1; $i < 13; $i++) { echo $i . ": "; echo array_key_exists($i, $arr) ? $arr[$i] : 0; echo "<br>"; //radbrytning så det blir enklare att läsa output }

Producerar

1: 34 2: 0 3: 56 4: 750 5: 98 6: 0 7: 23 8: 0 9: 0 10: 67 11: 800 12: 54

Hej,

Tjusigt! Funkar perfekt. Jag var inne och försökte tidigare med en lösning med array_key_exists(), men den var inte i närheten så elegant som denna. Hur funkar ?-tecknet efter array_key_exist() funktionen?

Trädvy Permalänk
Medlem
Plats
Australien
Registrerad
Feb 2002
Skrivet av celoz:

Gör två iterationer "manuellt" så ser vi snabbt vad som är fel.

//sort[0] = 1 if ($sort[0] == 0) do blah else do blah ... //sort[1] = 3 if ($sort[1] == 1) do blah else do blah ...

Så du kollar om 1 = 0 och om 3 = 1, ditt villkor uppfylls aldrig.

Hej,

Om jag tilldelar fasta värden ser jag detta, har helt missat när jag har loopat med arrays. Har ändå försökt att ta koden ur sitt sammanhang och bara köra en test sida för att lättare se sånt här!

Tusen tack, din lösning är inlagd och funkar klockrent - hjälper till att generera data till en google chart, som linjediagram.

Trädvy Permalänk
Medlem
Plats
Australien
Registrerad
Feb 2002
Skrivet av Full Strike:

Nej, du kan inte göra så eftersom du ökar på i varje gång. Går att komma runt men skulle inte bli vackert.

Här är snyggaste lösningen jag kan se på rak arm (vet inte riktigt vilken och på vilket format du vill ha datan dock så dumpar bara ut den nu):

<?php $months = range(1, 12); $sort = array (1,3,4,5,7,10,11,12); $antal = array (34,56,750,98,23,67,800,54); $missing = array_values(array_diff($months,$sort)); $existing = array_combine($sort,$antal); echo "<pre>"; echo "<h3>Missing</h3>"; print_r($missing); echo "<h3>Values</h3>"; print_r($existing); echo "</pre>"; ?>

I $missing är då värdena månaderna som saknas. I $existing är nyckeln månaden och värdet antalet för den månaden.

Edit:
För att skriva ut det på samma sätt som du gjorde:

foreach($months as $month){ if(!in_array($month, $missing)){ echo "$month: {$existing[$month]} <br>"; }else{ echo "$month: 0 (missing) <br>"; } }

Go kväll!

Tusen tack för denna lösningen, såg den dock lite för sent - blev så till mig över lösningen innan!

Det är lätt att stirra sig blind när man håller på tycker jag, dessutom när man knappt kan kalla sig amatör längre utan snarare novis, eller nybörjare (även om första raden php skrev när php3 var det senaste man kunde ha, för en så där 15 år sen)...

Nu är det natten här, jag tackar er alla för er hjälp!

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Aug 2009
Skrivet av zajko:

Hej,

Tjusigt! Funkar perfekt. Jag var inne och försökte tidigare med en lösning med array_key_exists(), men den var inte i närheten så elegant som denna. Hur funkar ?-tecknet efter array_key_exist() funktionen?

echo array_key_exists($i, $arr) ? $arr[$i] : 0;

är samma som

if (array_key_exists($i, $arr)) echo $arr[$i]; else echo 0;

https://davidwalsh.name/php-shorthand-if-else-ternary-operato...

7900x @ 4,7ghz - 1080ti @ 2100