/ Forside / Teknologi / Udvikling / PHP / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
PHP
#NavnPoint
rfh 3959
natmaden 3372
poul_from 3310
funbreak 2700
stone47 2230
Jin2k 1960
Angband 1743
Bjerner 1249
refi 1185
10  Interkril.. 1146
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

Peter Brodersen skrev:

>at have ikke-normaliseret data :) Algoritmen er implementeret i php
>under funktionen natsort().

Det er jo helt poetisk.

--
Bertel
http://bertel.lundhansen.dk/   FIDUSO: http://fiduso.dk/

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

Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408929
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste