|
| Sortering af array Fra : Brian Emilius |
Dato : 26-10-04 20:31 |
|
Hej NG
$resultat = @mysql_query("SELECT * FROM menu");
while($raekke = @mysql_fetch_array($resultat)){
echo $raekke['id'];
}
Er der nogen måde hvorpå jeg, via PHP, kan sortere $raekke[] numerisk, når
feltet 'id' ser nogenlunde således ud: 1,1_1,2,2_1,3,4,4_1,4_2 (osv...)???
Problemet opstår i at feltet jo ikke er INT. Derfor resulterer en sortering
i noget i retning af: 1,2_1,2,3,4_1,4,4_2 (osv...).
Venlig hilsen
Brian Emilius
| |
Thomas Lindgaard (26-10-2004)
| Kommentar Fra : Thomas Lindgaard |
Dato : 26-10-04 21:10 |
|
On Tue, 26 Oct 2004 21:31:08 +0200, Brian Emilius wrote:
> Hej NG
>
> $resultat = @mysql_query("SELECT * FROM menu");
> while($raekke = @mysql_fetch_array($resultat)){
> echo $raekke['id'];
> }
>
> Er der nogen måde hvorpå jeg, via PHP, kan sortere $raekke[] numerisk, når
> feltet 'id' ser nogenlunde således ud: 1,1_1,2,2_1,3,4,4_1,4_2 (osv...)???
> Problemet opstår i at feltet jo ikke er INT. Derfor resulterer en sortering
> i noget i retning af: 1,2_1,2,3,4_1,4,4_2 (osv...).
>
> Venlig hilsen
> Brian Emilius
Æhm... prøv lige at køre følgende og se om det ikke er sorteret rigtigt:
<?php
$array = array('1','2_1','2','3','4_1','4','4_2');
sort($array);
print_r($array);
?>
Når du vælger noget fra en database uden at specificere en ordning, så
får du rækkerne i tilfældig orden. Hvis du siger
SELECT * FROM menu ORDER BY id
så vil jeg mene at du får det du ønsker.
Mvh.
/Thomas
| |
Peter Brodersen (26-10-2004)
| Kommentar Fra : Peter Brodersen |
Dato : 26-10-04 21:30 |
|
On Tue, 26 Oct 2004 22:10:12 +0200, Thomas Lindgaard
<thomas@it-snedkeren.BLACK_HOLE.dk> wrote:
>Æhm... prøv lige at køre følgende og se om det ikke er sorteret rigtigt:
>
> <?php
> $array = array('1','2_1','2','3','4_1','4','4_2');
> sort($array);
> print_r($array);
> ?>
Hvis der kun er ét ciffer, så ja. Men 11 vil fx blive sorteret før 2,
og tilsvarende vil 4_10 blive sorteret før 4_5.
Det kræver en mere intelligent sortering, som fx natural
order-algoritmen kan tilbyde - når man altså i første omgang er ude i
at have ikke-normaliseret data :) Algoritmen er implementeret i php
under funktionen natsort().
Mere om algoritmen:
http://sourcefrog.net/projects/natsort/
--
- Peter Brodersen
Ugens sprogtip: pc (og ikke PC)
| |
Bertel Lund Hansen (27-10-2004)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 27-10-04 08:12 |
| | |
Thomas Lindgaard (28-10-2004)
| Kommentar Fra : Thomas Lindgaard |
Dato : 28-10-04 08:28 |
|
On Tue, 26 Oct 2004 22:30:27 +0200, Peter Brodersen wrote:
> Hvis der kun er ét ciffer, så ja. Men 11 vil fx blive sorteret før 2,
> og tilsvarende vil 4_10 blive sorteret før 4_5.
Ja selvfølgelig - jeg nåede aldrig over 10 i min lille test :)
Mvh.
/Thomas
| |
Brian Emilius (26-10-2004)
| Kommentar Fra : Brian Emilius |
Dato : 26-10-04 23:15 |
|
"Thomas Lindgaard" <thomas@it-snedkeren.BLACK_HOLE.dk> skrev i en meddelelse
news:pan.2004.10.26.20.10.09.898818@it-snedkeren.BLACK_HOLE.dk...
> Når du vælger noget fra en database uden at specificere en ordning, så
> får du rækkerne i tilfældig orden. Hvis du siger
>
> SELECT * FROM menu ORDER BY id
>
> så vil jeg mene at du får det du ønsker.
Grunden til at jeg spørger herinde (og det kan du selvfølgelig ikke vide)
er, at jeg har forsøgt mig med flere muligheder via SQL, bl.a. CAST, men jeg
kunne ikke finde løsningen der, derfor mit indlæg i denne gruppe.
Det skal nok også lige siges at det felt, der skal sorteres, ikke er et
INT-felt, men et VARCHAR-felt. Dette har jeg valgt at gøre, så jeg ville
have milighed for at indsætte seperatortegn som fx '_'.
Venlig hilsen
Brian Emilius
| |
Peter Brodersen (26-10-2004)
| Kommentar Fra : Peter Brodersen |
Dato : 26-10-04 21:27 |
|
On Tue, 26 Oct 2004 21:31:08 +0200, "Brian Emilius" <msn@emilius.dk>
wrote:
>Er der nogen måde hvorpå jeg, via PHP, kan sortere $raekke[] numerisk, når
>feltet 'id' ser nogenlunde således ud: 1,1_1,2,2_1,3,4,4_1,4_2 (osv...)???
>Problemet opstår i at feltet jo ikke er INT. Derfor resulterer en sortering
>i noget i retning af: 1,2_1,2,3,4_1,4,4_2 (osv...).
natsort() gør præcis det, du ønsker. Der findes ingen lignende
funktion i MySQL.
Dokumentation:
http://dk2.php.net/natsort
Eksempel:
<?php
$a = array(
'2_1',
'4',
'3',
'4_2',
'1',
'4_1',
'11',
'4_11',
'4_5',
'11_100',
'4_15',
'11_20'
);
natsort($a);
print_r($a);
?>
Output:
Array
(
[4] => 1
[0] => 2_1
[2] => 3
[1] => 4
[5] => 4_1
[3] => 4_2
[8] => 4_5
[7] => 4_11
[10] => 4_15
[6] => 11
[11] => 11_20
[9] => 11_100
)
--
- Peter Brodersen
Ugens sprogtip: pc (og ikke PC)
| |
Brian Emilius (26-10-2004)
| Kommentar Fra : Brian Emilius |
Dato : 26-10-04 23:05 |
|
"Peter Brodersen" <usenet@ter.dk> skrev i en meddelelse
news:clmbv5$i8c$1@katie.ellegaard.dk...
> natsort() gør præcis det, du ønsker. Der findes ingen lignende
> funktion i MySQL.
Tak for dit svar, det ser ud som om det er den funktion, jeg skal bruge...
Men!
I mit eksempel tidligere, mener jeg at jeg lægger op til at $raekke er et
flerdimisionalt array (er det det man kalder det?), så når jeg skriver
natsort($raekke['id']); (der må jo være flere resultater af 'id', når der er
flere rækker i databasen) får jeg blot flg. fejl:
Warning: natsort(): The argument should be an array
Hvad gør jeg forkert? Jeg har også prøvet med natsort($raekke); men så
bliver arrayet ikke sorteret rigtigt.
Venlig hilsen
Brian Emilius
Eksempel for de nysgerrige, der ikke gider kigge længere oppe i tråden
$resultat = @mysql_query("SELECT * FROM menu");
while($raekke = @mysql_fetch_array($resultat)){
natsort($raekke['id']); // Peter Brodersens forslag...
echo $raekke['id'];
}
| |
Peter Brodersen (27-10-2004)
| Kommentar Fra : Peter Brodersen |
Dato : 27-10-04 08:21 |
|
On Wed, 27 Oct 2004 00:05:15 +0200, "Brian Emilius" <msn@emilius.dk>
wrote:
>I mit eksempel tidligere, mener jeg at jeg lægger op til at $raekke er et
>flerdimisionalt array (er det det man kalder det?), så når jeg skriver
>natsort($raekke['id']); (der må jo være flere resultater af 'id', når der er
>flere rækker i databasen) får jeg blot flg. fejl:
> Warning: natsort(): The argument should be an array
$raekke['id'] er på det tidspunkt ikke et array, men en scalar.
Ved at bruge
while($raekke = @mysql_fetch_array($resultat)){
trækker du hver række ud én efter én, og behandler dem individuelt. Du
kan evt. overveje at samle dem i ét array.
natsort() sorterer dog på værdierne, og ikke på nøglerne, så vi vil
bruge uksort() her i stedet for. Vi ender altså med noget i stil med:
<?php
$set = array();
$resultat = @mysql_query("SELECT * FROM menu");
// træk hele resultatet ud i et flerdimensionelt array
// med id som key
while($raekke = @mysql_fetch_array($resultat)){
$set[$raekke['id']] = $raekke;
}
// sortér på key
uksort($set,'strnatcmp');
// vis hvad vi er nået frem til
print_r($set);
?>
... igen vil jeg gerne ud ad sidebenet nævne, at det ikke virker som
verdens bedste datamodel, du i første omgang arbejder med.
--
- Peter Brodersen
Ugens sprogtip: pc (og ikke PC)
| |
Brian Emilius (27-10-2004)
| Kommentar Fra : Brian Emilius |
Dato : 27-10-04 14:41 |
|
"Peter Brodersen" <usenet@ter.dk> skrev i en meddelelse
news:clni9n$lo2$1@katie.ellegaard.dk...
> <?php
> $set = array();
> $resultat = @mysql_query("SELECT * FROM menu");
> // træk hele resultatet ud i et flerdimensionelt array
> // med id som key
> while($raekke = @mysql_fetch_array($resultat)){
> $set[$raekke['id']] = $raekke;
> }
> // sortér på key
> uksort($set,'strnatcmp');
> // vis hvad vi er nået frem til
> print_r($set);
> ?>
Dette giver et ekstremt (synes jeg) uoverskueligt output... hvordan gør jeg
det læseligt - eller spurgt på en anden måde, hvordan trækker jeg de enkelte
dele ud af $set?
> .. igen vil jeg gerne ud ad sidebenet nævne, at det ikke virker som
> verdens bedste datamodel, du i første omgang arbejder med.
Jah... min hjerne kan ikke lige overskue at lave databasen på en anden
måde...
Venlig hilsen
Brian Emilius
| |
Bent Stigsen (27-10-2004)
| Kommentar Fra : Bent Stigsen |
Dato : 27-10-04 16:19 |
|
Brian Emilius wrote:
> "Peter Brodersen" <usenet@ter.dk> skrev i en meddelelse
> news:clni9n$lo2$1@katie.ellegaard.dk...
>
[snip]
>
>>.. igen vil jeg gerne ud ad sidebenet nævne, at det ikke virker som
>>verdens bedste datamodel, du i første omgang arbejder med.
>
> Jah... min hjerne kan ikke lige overskue at lave databasen på en anden
> måde...
Jeg formoder dit datafelt er nemt at arbejde med et andet sted i dit
system. Og så behøver dit design ikke være mere mærkeligt end at have et
cpr-nummer stående i et felt. Det skal også klippes op for fx. at finde
personens alder.
/Bent
| |
Peter Brodersen (27-10-2004)
| Kommentar Fra : Peter Brodersen |
Dato : 27-10-04 18:26 |
|
On Wed, 27 Oct 2004 15:41:23 +0200, "Brian Emilius" <msn@emilius.dk>
wrote:
>> // vis hvad vi er nået frem til
>> print_r($set);
>> ?>
>
>Dette giver et ekstremt (synes jeg) uoverskueligt output... hvordan gør jeg
>det læseligt - eller spurgt på en anden måde, hvordan trækker jeg de enkelte
>dele ud af $set?
Det er bare print_r, der viser, hvad array'et indeholder. Det var mest
bare ment som et eksempel på at tingene blev sorteret korrekt.
Nu har du så et array, der er sorteret korrekt, og så skal du bruge
ordinære array-funktioner. Hvis du vil behandle den array for array -
ligesom når du normalt går gennem et mysql-resultat, så tilføjer du
fx:
foreach ($set AS $row) {
print "ID: ".$row['id']."<br>\n";
print "Data: ".$row['data']."<br>\n";
print "Whatnot: ".$row['whatnot']."<br>\n";
}
--
- Peter Brodersen
Ugens sprogtip: pc (og ikke PC)
| |
Brian Emilius (27-10-2004)
| Kommentar Fra : Brian Emilius |
Dato : 27-10-04 22:38 |
|
"Peter Brodersen" <usenet@ter.dk> skrev i en meddelelse
news:clolo7$c5p$1@katie.ellegaard.dk...
> foreach ($set AS $row) {
> print "ID: ".$row['id']."<br>\n";
> print "Data: ".$row['data']."<br>\n";
> print "Whatnot: ".$row['whatnot']."<br>\n";
> }
Mange tusinde millioner gange tak! Nu lykkedes det. Du har lige reddet min
dag... eller nat - det er jo ved at være sent
Venlig hilsen
Brian Emilius
| |
Bent Stigsen (26-10-2004)
| Kommentar Fra : Bent Stigsen |
Dato : 26-10-04 23:45 |
|
Peter Brodersen wrote:
> On Tue, 26 Oct 2004 21:31:08 +0200, "Brian Emilius" <msn@emilius.dk>
> wrote:
>
>>Er der nogen måde hvorpå jeg, via PHP, kan sortere $raekke[] numerisk, når
>>feltet 'id' ser nogenlunde således ud: 1,1_1,2,2_1,3,4,4_1,4_2 (osv...)???
>>Problemet opstår i at feltet jo ikke er INT. Derfor resulterer en sortering
>>i noget i retning af: 1,2_1,2,3,4_1,4,4_2 (osv...).
>
>
> natsort() gør præcis det, du ønsker. Der findes ingen lignende
> funktion i MySQL.
Nej, man må sno sig lidt.
use test;
CREATE TABLE xx154 (
id int(3) NOT NULL auto_increment,
felt varchar(10),
PRIMARY KEY (id)
);
insert into xx154(felt) values('1_1');
insert into xx154(felt) values('1');
insert into xx154(felt) values('12');
insert into xx154(felt) values('11');
insert into xx154(felt) values('4_1');
insert into xx154(felt) values('6');
insert into xx154(felt) values('5_1');
insert into xx154(felt) values('5');
insert into xx154(felt) values('2');
insert into xx154(felt) values('3');
insert into xx154(felt) values('4_2');
insert into xx154(felt) values('6_1');
insert into xx154(felt) values('4');
select
id, felt,
left(felt, instr(concat(felt, '_'),'_')-1)+0 as f1,
mid(felt, instr(concat(felt, '_'),'_')+1)+0 as f2
from xx154
order by f1, f2;
--
+----+------+------+------+
| id | felt | f1 | f2 |
+----+------+------+------+
| 2 | 1 | 1 | 0 |
| 1 | 1_1 | 1 | 1 |
| 9 | 2 | 2 | 0 |
| 10 | 3 | 3 | 0 |
| 13 | 4 | 4 | 0 |
| 5 | 4_1 | 4 | 1 |
| 11 | 4_2 | 4 | 2 |
| 8 | 5 | 5 | 0 |
| 7 | 5_1 | 5 | 1 |
| 6 | 6 | 6 | 0 |
| 12 | 6_1 | 6 | 1 |
| 4 | 11 | 11 | 0 |
| 3 | 12 | 12 | 0 |
+----+------+------+------+
13 rows in set (0.00 sec)
/Bent
| |
Brian Emilius (27-10-2004)
| Kommentar Fra : Brian Emilius |
Dato : 27-10-04 06:43 |
|
"Bent Stigsen" <ngap@thevoid.dk> skrev i en meddelelse
news:417ed374$0$44924$edfadb0f@dread15.news.tele.dk...
> select
> id, felt,
> left(felt, instr(concat(felt, '_'),'_')-1)+0 as f1,
> mid(felt, instr(concat(felt, '_'),'_')+1)+0 as f2
> from xx154
> order by f1, f2;
WOW!!! Jeg har set lyset
Kan du ikke lige beskrive kort hvad det er du har gjort? evt. lige komme med
en udvidelse, i tilfælde af felter der har flere seperatorer ('_') fx
1_2_3_4?
Venlig hilsen
Brian Emilius
| |
Jimmy (27-10-2004)
| Kommentar Fra : Jimmy |
Dato : 27-10-04 07:26 |
|
"Brian Emilius" <msn@emilius.dk> wrote in message
news:clncha$ajb$1@news.cybercity.dk...
> Kan du ikke lige beskrive kort hvad det er du har gjort? evt. lige komme
med
> en udvidelse, i tilfælde af felter der har flere seperatorer ('_') fx
> 1_2_3_4?
Er du sikker på at du i virkeligheden ikke skal have redesignet din database
så du ikke har den slags slam-data i den?
Hvorfor er der behov for at separere data med _?
Mvh
Jimmy
| |
Bent Stigsen (27-10-2004)
| Kommentar Fra : Bent Stigsen |
Dato : 27-10-04 08:09 |
|
Brian Emilius wrote:
> "Bent Stigsen" <ngap@thevoid.dk> skrev i en meddelelse
> news:417ed374$0$44924$edfadb0f@dread15.news.tele.dk...
>
>>select
>> id, felt,
>> left(felt, instr(concat(felt, '_'),'_')-1)+0 as f1,
>> mid(felt, instr(concat(felt, '_'),'_')+1)+0 as f2
>>from xx154
>>order by f1, f2;
>
> WOW!!! Jeg har set lyset
>
> Kan du ikke lige beskrive kort hvad det er du har gjort?
x1 = concat(felt, '_') :
klister en '_' på, så der med sikkerhed er mindst en.
x2 = instr(x1, '_')-1 :
finder positionen før '_', som vil være lig antallet karakterer i det
første tal.
left(felt, x2)+0 :
klipper de første x2 karakterer ud og plusser med 0 så strengen
konverteres til et tal.
Det er i princippet "bare" at kigge på de funktioner man har til
rådighed og så sætte sig til at fedte lidt med det.
> evt. lige komme med
> en udvidelse, i tilfælde af felter der har flere seperatorer ('_') fx
> 1_2_3_4?
Kræver lidt mere fedteri :) Alt hvad du skal bruge står her:...
http://dev.mysql.com/doc/mysql/en/String_functions.html
Hvis du har rigtigt mange rækker i tabellen, får du måske et performance
problem afhængig af situationen, og så kan du blive nødsaget til at
revurdere designet, som Jimmy foreslår.
/Bent
| |
|
|