omgekeerde range()
Ik ben op zoek naar een scriptje of functie die het volgende voor mij kan doen:
De cijfers "1, 2, 3, 4 en 5" versimpelen naar "1 - 5" (1 tot en met 5 dus), maar ook:
"1 2 3 5 6 7" naar "1 - 3, 5 - 7".
Voor mijn gevoel is dit de functie range() omgekeerd, maar ik weet dus niet hoe ik dit voor elkaar moet krijgen.
De getallen worden nu weergegeven door een simpele echo, dit kan worden omgezet naar en array.
Hopelijk kan iemand mij hiermee helpen,
grzz. Johan.
Gewijzigd op 01/01/1970 01:00:00 door Johan M
Quote:
range() geeft een array van elementen van low naar high, inclusief. Wanneer low > high, dan zal de reeks lopen van high naar low.
Daarnaast kun je een array ook sorteren, zowel van laag naar hoog als hoog naar laag. Zie sort() en zijn vriendjes.
123567 eerst in een array zetten, en dan met een for lus (van min naar het max nummer wat er in staat) controleren of alle waarden er in staan die tussen - en max zitten.
Sla dan de beginwaarde op in een variabele (Array is handigst!!) en begin met het doorlopen van de mogelijkheden. Staat een waarde niet in de array, neem dan die waarde -1 als laatste waarde, en start een nieuwe reeks die verder telt dan waar je bent.
Maar je zit wel met een probleem als je hoger dan 10 komt, want hoe bepaal je:
123567910 dat dan de 10 niet gewoon 1 en 0 zijn?
Quote:
Gooi er dan gewoon even een array_reverse() over en klaar is kees of in dit geval Johan.range() geeft een array van elementen van low naar high , inclusief. Wanneer low > high, dan zal de reeks lopen van high naar low.
Ik hoopte dat er een of andere functie voor zou zijn, maar aangezien niemand die noemt begrijp ik dat het niet eens zo'n heel slechte vraag was.
Robert_Deiman schreef op 23.01.2008 16:29:
Dit probleem is denk ik niet aan de orde omdat all getallen gescheiden zijn. Hetzij door komma's of spaties o.i.d., of als aparte variabelen in een array, dat maakt niet uit....
123567910 dat dan de 10 niet gewoon 1 en 0 zijn?
123567910 dat dan de 10 niet gewoon 1 en 0 zijn?
Ik ken daar inderdaad geen functie voor, en het is geen slechte vraag. Vind 't wel een leuk vraagstuk eigenlijk.
Hopelijk kan je wat met mijn suggestie..
Code (php)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
<?php
ini_set('display_errors', 1); // 0 = uit, 1 = aan
error_reporting(E_ALL);
$arr = array_merge(range(1, 5), range('z', 'm'), array(9, 'A'), range(8, 4));
echo '<pre>';
print_r($arr);
echo '</pre>';
?>
ini_set('display_errors', 1); // 0 = uit, 1 = aan
error_reporting(E_ALL);
$arr = array_merge(range(1, 5), range('z', 'm'), array(9, 'A'), range(8, 4));
echo '<pre>';
print_r($arr);
echo '</pre>';
?>
Edit: Volgens mij heb ik de vraag niet goed gelezen. Sorry. :-)
Gewijzigd op 01/01/1970 01:00:00 door - SanThe -
Creatief hoor SanThe, maar idd niet helemaal wat ik zoek :)
Hoe krijg je die data binnen? In een string? Met komma's, spaties of wat dan ook er tussen? Zijn het altijd alleen getallen?
Het zijn inderdaad altijd alleen getallen die uit een SQL-database komen, nu geef ik ze weer met een echo, maar dit zou net zo makkelijk een array kunnen worden. Hier valt altijd wel een mouw aan te passen. Hoe de getallen gescheiden worden maakt dus ook niet uit.
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
30
31
32
33
34
35
36
37
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
30
31
32
33
34
35
36
37
<?php
//string with space separated
$sSpacesep = '1 2 3 4 6 7 8 10 11 12';
//string with comma separated
$sCommasep = '1,2,3,5,6,7,12,13,14,16';
function createrange($sString,$separator = ' '){
$aNumbers = explode($separator,$sString);
$j=1;
$aNumarray = array();
for($i=1; $i <= max($aNumbers); $i++){
if(in_array($i,$aNumbers)){
$aNumarray[$j][] = $i;
}
else{
$j++;
}
}
$sRange = '';
foreach($aNumarray as $key => $value){
if(count($aNumarray[$key]) > 1){
$sRange .= min($aNumarray[$key]).'-'.max($aNumarray[$key]).' ';
}
else{
$sRange .= min($aNumarray[$key]).' ';
}
}
return $sRange;
}
// example for how to use it with a space separated string
echo createrange($sSpacesep);
// example for how to use it with a comma separated string
echo '<br />';
echo createrange($sCommasep,',');
?>
//string with space separated
$sSpacesep = '1 2 3 4 6 7 8 10 11 12';
//string with comma separated
$sCommasep = '1,2,3,5,6,7,12,13,14,16';
function createrange($sString,$separator = ' '){
$aNumbers = explode($separator,$sString);
$j=1;
$aNumarray = array();
for($i=1; $i <= max($aNumbers); $i++){
if(in_array($i,$aNumbers)){
$aNumarray[$j][] = $i;
}
else{
$j++;
}
}
$sRange = '';
foreach($aNumarray as $key => $value){
if(count($aNumarray[$key]) > 1){
$sRange .= min($aNumarray[$key]).'-'.max($aNumarray[$key]).' ';
}
else{
$sRange .= min($aNumarray[$key]).' ';
}
}
return $sRange;
}
// example for how to use it with a space separated string
echo createrange($sSpacesep);
// example for how to use it with a comma separated string
echo '<br />';
echo createrange($sCommasep,',');
?>
Edit:
De wijziging bevat nu ook dat je een losstaand nummer ook goed weergegeven wordt.
De wijziging bevat nu ook dat je een losstaand nummer ook goed weergegeven wordt.
Gewijzigd op 01/01/1970 01:00:00 door Robert Deiman
Maar om iets te maken wat er mee om kan gaan, moet je op zijn minst weten hoe je het binnen krijgt.
SanThe schreef op 23.01.2008 18:53:
Maar om iets te maken wat er mee om kan gaan, moet je op zijn minst weten hoe je het binnen krijgt.
@SanThe
Zie mijn voorbeeldfunctie ;) Hij gaat er standaard vanuit dat het met een spatie is gescheiden, maar ook met , of elk ander leesteken is prima mogelijk als je dat maar aangeeft.
Je kan ook bijvoorbeeld (omdat je weet dat er alleen maar gehele getallen in mogen staan) controleren een array samenstellen met alle mogelijke scheidingstekens. Komt 1 van die tekens voor, dan kan je het daarop laten scheiden.
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php
//string with space separated
$sSpacesep = '1 2 3 4 6 7 8 10 11 12';
//string with comma separated
$sCommasep = '1,2,3,5,6,7,12,13,14,16';
function createrange($sString,$separator = ' '){
if(!is_array($sString)){
$aNumbers = explode($separator,$sString);
}
else{
$aNumbers = $sString;
}
$j=1;
$aNumarray = array();
for($i=1; $i <= max($aNumbers); $i++){
if(in_array($i,$aNumbers)){
$aNumarray[$j][] = $i;
}
else{
$j++;
}
}
$sRange = '';
foreach($aNumarray as $key => $value){
if(count($aNumarray[$key]) > 1){
$sRange .= min($aNumarray[$key]).'-'.max($aNumarray[$key]).' ';
}
else{
$sRange .= min($aNumarray[$key]).' ';
}
}
return $sRange;
}
// example for how to use it with a space separated string
echo createrange($sSpacesep);
// example for how to use it with a comma separated string
echo '<br />';
echo createrange($sCommasep,',');
?>
//string with space separated
$sSpacesep = '1 2 3 4 6 7 8 10 11 12';
//string with comma separated
$sCommasep = '1,2,3,5,6,7,12,13,14,16';
function createrange($sString,$separator = ' '){
if(!is_array($sString)){
$aNumbers = explode($separator,$sString);
}
else{
$aNumbers = $sString;
}
$j=1;
$aNumarray = array();
for($i=1; $i <= max($aNumbers); $i++){
if(in_array($i,$aNumbers)){
$aNumarray[$j][] = $i;
}
else{
$j++;
}
}
$sRange = '';
foreach($aNumarray as $key => $value){
if(count($aNumarray[$key]) > 1){
$sRange .= min($aNumarray[$key]).'-'.max($aNumarray[$key]).' ';
}
else{
$sRange .= min($aNumarray[$key]).' ';
}
}
return $sRange;
}
// example for how to use it with a space separated string
echo createrange($sSpacesep);
// example for how to use it with a comma separated string
echo '<br />';
echo createrange($sCommasep,',');
?>
En in deze versie maakt het niet uit of er een array of een string als input wordt gegeven.
Gewijzigd op 01/01/1970 01:00:00 door Robert Deiman
@ SanThe: dat maakt mij dus niet uit, ikzelf was iets aan het proberen op een manier waarmee het als array binnen komt, maar ik schreef dat het nu wordt weergegeven als een lijst met getallen. Daarom is Robert's manier nog mekkelijker! Het is net de manier waarop jij er iets mee kunt om dit op te lossen, de input die er in moet krijg ik wel voor elkaar.
Dat losse getal kan eventueel opgelost worden door een "if (mysql_num_rows($result) == 0)", maar lijkt met met deze laatste versie niet meer nodig.
Gewijzigd op 01/01/1970 01:00:00 door Johan M
Dat losse getal is in ondertussen al opgelost, hij kijkt of er wel meer dan 1 waarden staan in een array. Zo ja, dan komen de min en de max met een streepje ertussen. Is het er maar 1, dan komt de enige waarde gewoon los in de output.
Het is nu in de laatste versie ook mogelijk om via een array te werken, als je dat prettiger vind.
Maar misschien dat het nog mooier is om 2 getallen die achter elkaar komen (5 en 6 die bijv met zijn 2'en bij elkaar blijven) gewoon met een comma te doen. Ga ik ook nog even inbouwen.
In ieder geval super bedankt voor deze functie, hij werkt super. Met de update die je voorstelt erbij lijkt het me helemaal geweldig.
Ik had lang zitten tobben en zitten Googlen, maar ik kwam er niet uit, dus ik ben heel blij dat er hier zo fantastisch meegedacht wordt.
Johan schreef op 23.01.2008 18:45:
En waarom sorteer je niet in de query? SQL kent niet voor niks de optie ORDER BY....Het zijn inderdaad altijd alleen getallen die uit een SQL-database komen
1,2,3,5
10,14,20,100
21,22,23,24,30,31,32,33,34
Daarom wil ik per regel (deze zouden wel eens heel lang kunnen worden) dat er dit wordt weergegven:
1-3, 5
10, 14, 20, 100
21-24, 30-34
Dit voor het overzicht, en dat gaat volgens mij helemaal lukken met Robert's function. Mocht je dit kunnen oplossen via de SQL, vertel het me dan graag!
(ik vrees het ergste, het ziet eruit als gesorteerde tekst en geen getallen...)