Simpelere increasement van een value binnen multi-array
Zie graag onderstaand voorbeeld, is er een manier om dit korter schrijven dan met 3 keer "$aArray['test'][$vValue]"?
Om redenen die niet zijn opgenomen in dit voorbeeld is hier een multidimensionale-array nodig, vandaar nu de 'test'-key.
N.b.: Ik ben me bewust van simpele functies als bijvoorbeeld count() en het gaat vanzelfsprekend niet om het opzoeken van het aantal keer dat 'a' voorkomt in $aVoorbeeld, dat zou een andere vraag zijn, het gaat mij om het korter schrijven van de regel waarop de key's worden aangemaakt zonder een Notice te krijgen dat de key niet bestaat (wanneer je bijvoorbeeld "$aArray['test'][$vValue]++;" of "$aArray['test'][$vValue] += 1;" zou doen:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
$aVoorbeeld = array('a', 'b', 'c', 'a', 'a', 'c', 'd');
$aArray = array();
foreach($aVoorbeeld AS $vValue)
{
$aArray['test'][$vValue] = isset($aArray['test'][$vValue]) ? $aArray['test'][$vValue] + 1 : 1;
}
print_r($aArray);
/*
Gewenste output:
Array
(
[test] => Array
(
[a] => 3
[b] => 1
[c] => 2
[d] => 1
)
)
*/
?>
$aVoorbeeld = array('a', 'b', 'c', 'a', 'a', 'c', 'd');
$aArray = array();
foreach($aVoorbeeld AS $vValue)
{
$aArray['test'][$vValue] = isset($aArray['test'][$vValue]) ? $aArray['test'][$vValue] + 1 : 1;
}
print_r($aArray);
/*
Gewenste output:
Array
(
[test] => Array
(
[a] => 3
[b] => 1
[c] => 2
[d] => 1
)
)
*/
?>
Ik hoor het graag!
Dat begrijp ik, maar zoals ik probeerde te schrijven ben ik op zoek naar een nette, kortere manier om de array aan te maken. Iemand een idee?
Blijkbaar niet ;-)
Je had ook even moeite kunnen doen om de link te bekijken die Thomas hierboven aandraagt, want daar staat het antwoord gewoon in.
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
<?php
$aVoorbeeld = array('a', 'b', 'c', 'a', 'a', 'c', 'd');
$aArray['test'] = array_count_values($aVoorbeeld);
print_r($aArray);
?>
$aVoorbeeld = array('a', 'b', 'c', 'a', 'a', 'c', 'd');
$aArray['test'] = array_count_values($aVoorbeeld);
print_r($aArray);
?>
De array $aVoorbeeld bestaat uit meer regels dan alleen bovengenoemd (input waarop ik geen invloed heb) welke bestaan uit 2 type strings als waarde. Afhankelijk van het type wordt de eerste key van de array bepaald, waarna de volgende waarden uit de oorspronkelijke input-array hiervan het child worden, totdat er een nieuwe 1e-key-waarde langskomt.
De vraag blijft dus opnieuw onveranderd, vandaar dat ik in mijn beginpost al schreef dat het hier om een voorbeeld ging.
Om verdere verwarring te voorkomen en de reden waarom ik het hier vraag duidelijker te maken hierbij een duidelijkere voorbeeld-array:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
$aVoorbeeld = array('key_1', 'a', 'b', 'b', 'c', 'key_2', 'a', 'a', 'c', 'd', 'd');
/*
Gewenste output:
Array
(
[key_1] => Array
(
[a] => 1
[b] => 2
[c] => 1
)
[key_2] => Array
(
[a] => 2
[c] => 1
[d] => 2
)
)
*/
?>
$aVoorbeeld = array('key_1', 'a', 'b', 'b', 'c', 'key_2', 'a', 'a', 'c', 'd', 'd');
/*
Gewenste output:
Array
(
[key_1] => Array
(
[a] => 1
[b] => 2
[c] => 1
)
[key_2] => Array
(
[a] => 2
[c] => 1
[d] => 2
)
)
*/
?>
Op deze input heb ik dus geen invloed anders had ik dit vanzelfsprekend anders aangepakt!
Ik ben niet iemand die voor het eerst met PHP bezig is of iemand die voor school een blog op moet zetten en te lui is om zelf iets te maken, ik probeer een serieuze vraag te stellen. Ik heb een werkend script welke ik hierboven voor de duidelijkheid (hoopte ik) ingekort had, jullie geven nuttige antwoorden, echter niet op de vraag zoals ik deze bedoelde te stellen.
Ik kan me vooral niet voorstellen dat er voor bovengenoemde oplossing op regel 8 van mijn eerste post geen simpelere manier is?
Gewijzigd op 06/04/2016 13:43:08 door Johan M
@Johan M, Hoe weet je uit jouw voorbeeld dat key_1 en key_2 "keys" zijn en a, b, c, d "values"?
Anyhow, die $aVoorbeeld is in werkelijkheid op dezelfde manier opgebouwd? Hoe weet je dan wat een key is en wat de childs zijn? Het zijn nu namelijk gewoon allemaal values.
Jan de Laet op 06/04/2016 13:45:17:
@Johan M, Hoe weet je uit jouw voorbeeld dat key_1 en key_2 "keys" zijn en a, b, c, d "values"?
Dit gebeurt d.m.v. een simpele vergelijking op het eerste gedeelte van elke string met substr(), de input betreft diverse gescande barcodes waarbij de werkordernummers gescande Code39 barcodes zijn en de artikelnummers gescande Code/EAN128-codes zijn. De scanners geven hierbij "BW-" terug bij Code39 en "KP-" terug aan het begin van de string bij Code128. Zoals gezegd heb ik dit niet verzonnen en heb ik hier verder geen invloed op helaas.
Ozzie PHP op 06/04/2016 13:48:35:
Dan had je het beter de 1e keer even op de juiste manier uitgelegd, want nu schotel je een andere situatie voor dan je in eerste instantie deed.
Anyhow, die $aVoorbeeld is in werkelijkheid op dezelfde manier opgebouwd? Hoe weet je dan wat een key is en wat de childs zijn? Het zijn nu namelijk gewoon allemaal values.
Anyhow, die $aVoorbeeld is in werkelijkheid op dezelfde manier opgebouwd? Hoe weet je dan wat een key is en wat de childs zijn? Het zijn nu namelijk gewoon allemaal values.
Ik hoopte het duidelijk uitgelegd te hebben door het voorbeeld simpel te houden, excuses als dit voor verwarring heeft gezorgd. Ik had er duidelijk bijstaan dat het een voorbeeld betrof en hoop dat er een nettere oplossing is voor regel 8.
Je vraag heb ik hierboven beantwoord!
Kun je dat array niet meteen fatsoenlijk opbouwen, of een fatsoeneringsstap tussenvoegen, dan kun je namelijk wederom van array_count_values() gebruik maken per subarray. Het probleem is ook niet zozeer het tellen an sich, maar het ontstaat meer door een gebrek aan structuur in je dataset...
$aVoorbeeld = array('key_1', 'a', 'b', 'b', 'c', 'key_2', 'a', 'a', 'c', 'd', 'd');
Zoals gezegd heb ik geen invloed op deze input, dit is nou eenmaal hoe de scanners dit teruggeven.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
// hierbij gaan we ervan uit dat je invoer klopt, en dus altijd begint met een key
function sortShizzleByKey($in) {
$out = array();
$currentKey = false;
foreach ($in as $value) {
// voer hier een controle uit om te zien of het een "key" betreft
if (substr($value, 0, 4) === 'key_') {
$currentKey = $value;
$out[$currentKey] = array();
} else {
$out[$currentKey][] = $value;
}
}
return $out;
}
$test = array('key_1', 'a', 'b', 'b', 'c', 'key_2', 'a', 'a', 'c', 'd', 'd');
echo '<pre>'.print_r(sortShizzleByKey($test), true).'</pre>';
?>
// hierbij gaan we ervan uit dat je invoer klopt, en dus altijd begint met een key
function sortShizzleByKey($in) {
$out = array();
$currentKey = false;
foreach ($in as $value) {
// voer hier een controle uit om te zien of het een "key" betreft
if (substr($value, 0, 4) === 'key_') {
$currentKey = $value;
$out[$currentKey] = array();
} else {
$out[$currentKey][] = $value;
}
}
return $out;
}
$test = array('key_1', 'a', 'b', 'b', 'c', 'key_2', 'a', 'a', 'c', 'd', 'd');
echo '<pre>'.print_r(sortShizzleByKey($test), true).'</pre>';
?>
And Bob's your uncle.
Dit had ik zelf ook voor elkaar op deze manier:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Gewijzigd op 06/04/2016 14:46:19 door Johan M
Gewijzigd op 06/04/2016 14:50:22 door Thomas van den Heuvel
En om dan nog een beetje flauw te doen, is er echt geen oplossing om dit korter en netter te doen i.p.v. met 3 keer hetzelfde:
$aArray['test'][$vValue] = isset($aArray['test'][$vValue]) ? $aArray['test'][$vValue] + 1 : 1;
Daarnaast zoek je enkel naar een "kortste oplossing" voor dit specifieke probleem, maar hoe gebruik je deze data verder? Dit zou moeten bepalen hoe je datastructuur er uit ziet, zodat je hier -in het algemeen- makkelijk mee kunt werken.
Wat is er op tegen om een probleem op te splitsen in deelproblemen, die mogelijk ook andere zaken gelijk tacklen (zoals het opzetten van een datastructuur die makkelijker is in het gebruik), in plaats van enkel een ad hoc oplossing te schrijven die enkel geschikt is voor een direct probleem?
Duidelijk verhaal Thomas, hartelijk dank voor het meedenken!
Code (php)
1
$aArray['test'][$vValue] = isset($aArray['test'][$vValue]) ? $aArray['test'][$vValue] + 1 : 1;
Dit is al een verkort geschreven stukje code voor een IF-THEN-ELSE
Wil je het duidelijker dan kan je het als volgt doen :
Code (php)
1
2
3
2
3
if (isset($aArray['test'][$vValue]))
$aArray['test'][$vValue] = $aArray['test'][$vValue] + 1;
else $aArray['test'][$vValue] = 1;
$aArray['test'][$vValue] = $aArray['test'][$vValue] + 1;
else $aArray['test'][$vValue] = 1;
De coderegel na het if-statement kan eventueel alsvolgt geschreven worden :
Dat is wel iets korter.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
$aVoorbeeld = array('key_1', 'a', 'b', 'b', 'c', 'key_2', 'a', 'a', 'c', 'd', 'd');
$aArray = array();
$key = '';
while($shift = array_shift($aVoorbeeld))
{
if(substr($shift, 0, 3) == 'key')
{
$key = $shift;
$aArray[$key] = array();
}
else
{
$aArray[$key][$shift] = isset($aArray[$key][$shift]) ? $aArray[$key][$shift]+1 : 1;
}
}
print_r($aArray);
?>
$aVoorbeeld = array('key_1', 'a', 'b', 'b', 'c', 'key_2', 'a', 'a', 'c', 'd', 'd');
$aArray = array();
$key = '';
while($shift = array_shift($aVoorbeeld))
{
if(substr($shift, 0, 3) == 'key')
{
$key = $shift;
$aArray[$key] = array();
}
else
{
$aArray[$key][$shift] = isset($aArray[$key][$shift]) ? $aArray[$key][$shift]+1 : 1;
}
}
print_r($aArray);
?>
Gewijzigd op 06/04/2016 21:56:35 door - SanThe -