Avatar billede hoppe11 Nybegynder
01. april 2009 - 16:48 Der er 31 kommentarer og
1 løsning

sortere flerdimensionelt array

hvordan er det muligt at sortere et flerdimensionelt array?

eks.
$arr[0] = [2, 4];
$arr[1] = [0, 1];
$arr[2] = [7, 2];
$arr[3] = [3, 5];
$arr[4] = [3, 7];

jeg skal så sortere mit array med den første værdi som første prioritet og med anden værdi som anden prioritet (hvis der skulle forekomme flere med samme første værdi)

$arr[2] = [7, 2];
$arr[4] = [3, 7];
$arr[3] = [3, 5];
$arr[0] = [2, 4];
$arr[1] = [0, 1];
Avatar billede arne_v Ekspert
01. april 2009 - 17:00 #1
proev med:

usort($arr, "cmp");

hvor:


function cmp($a, $b) {
    if($a[0] < $b[0]) {
        return -1;
    } else if($a[0] > $b[0]) {
        return 1;
    } else {
        if($a[1] < $b[1]) {
            return -1;
        } else if($a[1] > $b[1]) {
            return 1;
        } else {
            return 0;
        }
    }
}
Avatar billede hoppe11 Nybegynder
01. april 2009 - 19:29 #2
det fungerer ikke helt

$arr = array(
    0 => array(2,4),
    1 => array(0,19),
    2 => array(7,2),
    3 => array(3,5),
    4 => array(3,7)
    );

echo '<pre>';
print_r($arr);
echo '</pre>';

function cmp($a, $b) {
    if($a[0] < $b[0]) {
        return -1;
    } else if($a[0] > $b[0]) {
        return 1;
    } else {
        if($a[1] < $b[1]) {
            return -1;
        } else if($a[1] > $b[1]) {
            return 1;
        } else {
            return 0;
        }
    }
}

usort($arr, "cmp");

echo '<pre>';
print_r($arr);
echo '</pre>';
Avatar billede hoppe11 Nybegynder
01. april 2009 - 19:30 #3
den skal køre "asc"
Avatar billede hoppe11 Nybegynder
01. april 2009 - 19:34 #4
er det her korrekt? :)

function cmp($a, $b)
{
    if($a[0] < $b[0]) return 1;
    elseif($a[0] > $b[0]) return -1;
    else
    {
        if($a[1] < $b[1]) return 1;
        elseif($a[1] > $b[1]) return -1;
        else return 0;
    }
}
Avatar billede arne_v Ekspert
01. april 2009 - 19:51 #5
Koden i #2 sorterer ASC hos mig.

Mener du DESC ?

I saa fald er det bare at bytte om paa 1 og -1.
Avatar billede arne_v Ekspert
01. april 2009 - 19:52 #6
cmp kan vist ioevrigt kortes lidt ned naar det er tal, da man bare kan traekke dem fra hinanden.
Avatar billede hoppe11 Nybegynder
01. april 2009 - 21:15 #7
ja, jeg skrev forkert først.. mente DESC

scriptet virker fint nu, men den "nulstiller" alle keys i første dimension i arrayet.. :(
Avatar billede hoppe11 Nybegynder
01. april 2009 - 21:20 #8
nøglen i første dimension virker som et id

men hvordan kan det kortes ned?
Avatar billede hoppe11 Nybegynder
01. april 2009 - 21:44 #9
eneste mulighed for at sortere på den her måde er så at flytte alle værdier inkl. id'et ud på samme "dimension"?
Avatar billede arne_v Ekspert
01. april 2009 - 21:49 #10
function cmp($a, $b) {
    if($a[0] == $b[0]) {
        return $b[1] - $a[1];
    } else {
        return $b[0] - $a[0];
    }
}
Avatar billede hoppe11 Nybegynder
01. april 2009 - 21:57 #11
hvordan vil cmp-funktionen se ud hvis jeg smider alle tre værdier på række?

altså

cmp($a, $b, $c)

- hvor $a er mit id og $b og $c er dem jeg skal sortere efter...
Avatar billede hoppe11 Nybegynder
01. april 2009 - 22:00 #12
min struktur ser nu således ud:

Array
(
    [0] => Array
        (
            [0] => 23006
            [1] => 1
            [2] => 3
        )

    [1] => Array
        (
            [0] => 11258
            [1] => 3
            [2] => 1
        )

    [2] => Array
        (
            [0] => 26394
            [1] => 1
            [2] => 3
        )

    [3] => Array
        (
            [0] => 49385
            [1] => 1
            [2] => 5
        )

    [4] => Array
        (
            [0] => 70468
            [1] => 1
            [2] => 1
        )

    [5] => Array
        (
            [0] => 50911
            [1] => 1
            [2] => 1
        )

    [6] => Array
        (
            [0] => 74502
            [1] => 1
            [2] => 1
        )

)
Avatar billede arne_v Ekspert
01. april 2009 - 22:09 #13
function cmp($a, $b) {
    if($a[0] == $b[0]) {
        if($a[0] == $b[0]) {
            return $b[2] - $a[2];
        } else {
            return $b[1] - $a[1];
        }
    } else {
        return $b[0] - $a[0];
    }
}
Avatar billede hoppe11 Nybegynder
01. april 2009 - 22:12 #14
jeg er ikke helt med? kunne man ikke "springe over" første værdi og sortere efter [1] og [2] i stedet? har mit id på [0]
Avatar billede hoppe11 Nybegynder
01. april 2009 - 22:13 #15
hov undskyld.. :)

resultatet på den seneste bliver sådan her

Array
(
    [0] => Array
        (
            [0] => 74502
            [1] => 1
            [2] => 1
        )

    [1] => Array
        (
            [0] => 70468
            [1] => 1
            [2] => 1
        )

    [2] => Array
        (
            [0] => 50911
            [1] => 1
            [2] => 1
        )

    [3] => Array
        (
            [0] => 49385
            [1] => 1
            [2] => 5
        )

    [4] => Array
        (
            [0] => 26394
            [1] => 1
            [2] => 3
        )

    [5] => Array
        (
            [0] => 23006
            [1] => 1
            [2] => 3
        )

    [6] => Array
        (
            [0] => 11258
            [1] => 3
            [2] => 1
        )

)

Array
(
    [0] => Array
        (
            [0] => 74502
            [1] => 1
            [2] => 1
        )

    [1] => Array
        (
            [0] => 70468
            [1] => 1
            [2] => 1
        )

    [2] => Array
        (
            [0] => 50911
            [1] => 1
            [2] => 1
        )

    [3] => Array
        (
            [0] => 49385
            [1] => 1
            [2] => 5
        )

    [4] => Array
        (
            [0] => 26394
            [1] => 1
            [2] => 3
        )

    [5] => Array
        (
            [0] => 23006
            [1] => 1
            [2] => 3
        )

    [6] => Array
        (
            [0] => 11258
            [1] => 3
            [2] => 1
        )

)
Avatar billede arne_v Ekspert
01. april 2009 - 22:18 #16
sorry - jeg troede at du ville sortere efter alle felter

function cmp($a, $b) {
    if($a[1] == $b[1]) {
        return $b[2] - $a[2];
    } else {
        return $b[1] - $a[1];
    }
}
Avatar billede hoppe11 Nybegynder
01. april 2009 - 22:21 #17
helt kanon.. det virker :)

jeg skal vist lige ind i den callback-ting her

smid et svar..
Avatar billede arne_v Ekspert
01. april 2009 - 22:26 #18
svar
Avatar billede arne_v Ekspert
01. april 2009 - 22:27 #19
Hvis du brugte strenge som keys paa de indre arrays fremfor integers saa ville det maaske forbedre laesbarheden.

Hvis det skal vaere integers saa bruge konstanter.
Avatar billede hoppe11 Nybegynder
01. april 2009 - 22:35 #20
hvad mener du? er ikke helt med?
Avatar billede arne_v Ekspert
01. april 2009 - 22:39 #21
strenge eller konstanter ?
Avatar billede hoppe11 Nybegynder
01. april 2009 - 22:46 #22
hvordan vil du bruge en konstant i eksemplet her?

men du mener at søgetiden ville optimeres hvis det var tekststrenge?

vil du ikke prøve at lave et eksempel med en array struktur?
Avatar billede arne_v Ekspert
01. april 2009 - 23:01 #23
Nej - performance ville snaere blive ringere (men det vil skulle maales i milliardtedele sekunder)  - men koden ville blive nemme at laese.
Avatar billede arne_v Ekspert
01. april 2009 - 23:01 #24
Jeg kan lave et par eksempler.

Om en 3-4 timer.
Avatar billede hoppe11 Nybegynder
01. april 2009 - 23:14 #25
ok :)
Avatar billede arne_v Ekspert
02. april 2009 - 21:27 #26
Det tog lidt laengere tid.

:-)
Avatar billede arne_v Ekspert
02. april 2009 - 21:27 #27
<?php
$arr = array(0 => array( 0 => 23006, 1 => 1, 2 => 3),
            1 => array( 0 => 11258, 1 => 3, 2 => 1),
            2 => array( 0 => 26394, 1 => 1, 2 => 3),
            3 => array( 0 => 49385, 1 => 1, 2 => 5),
            4 => array( 0 => 70468, 1 => 1, 2 => 1),
            5 => array( 0 => 50911, 1 => 1, 2 => 1),
            6 => array( 0 => 74502, 1 => 1, 2 => 1));

echo "<pre>\r\n";
foreach($arr as $elm) {
    echo $elm[0] . " " . $elm[1] . " " . $elm[2] . "<br>\r\n";
}
echo "</pre>\r\n";

function cmp($a, $b) {
    if($a[1] == $b[1]) {
        return $b[2] - $a[2];
    } else {
        return $b[1] - $a[1];
    }
}

usort($arr, "cmp");

echo "<pre>\r\n";
foreach($arr as $elm) {
    echo $elm[0] . " " . $elm[1] . " " . $elm[2] . "<br>\r\n";
}
echo "</pre>\r\n";
?>
Avatar billede arne_v Ekspert
02. april 2009 - 21:27 #28
<?php
$arr = array(0 => array( 'id' => 23006, 'v1' => 1, 'v2' => 3),
            1 => array( 'id' => 11258, 'v1' => 3, 'v2' => 1),
            2 => array( 'id' => 26394, 'v1' => 1, 'v2' => 3),
            3 => array( 'id' => 49385, 'v1' => 1, 'v2' => 5),
            4 => array( 'id' => 70468, 'v1' => 1, 'v2' => 1),
            5 => array( 'id' => 50911, 'v1' => 1, 'v2' => 1),
            6 => array( 'id' => 74502, 'v1' => 1, 'v2' => 1));

echo "<pre>\r\n";
foreach($arr as $elm) {
    echo $elm['id'] . " " . $elm['v1'] . " " . $elm['v2'] . "<br>\r\n";
}
echo "</pre>\r\n";

function cmp($a, $b) {
    if($a['v1'] == $b['v1']) {
        return $b['v2'] - $a['v2'];
    } else {
        return $b['v1'] - $a['v1'];
    }
}

usort($arr, "cmp");

echo "<pre>\r\n";
foreach($arr as $elm) {
    echo $elm['id'] . " " . $elm['v1'] . " " . $elm['v2'] . "<br>\r\n";
}
echo "</pre>\r\n";
?>
Avatar billede arne_v Ekspert
02. april 2009 - 21:27 #29
<?php
define('ID', 0);
define('V1', 1);
define('V2', 2);

$arr = array(0 => array( ID => 23006, V1 => 1, V2 => 3),
            1 => array( ID => 11258, V1 => 3, V2 => 1),
            2 => array( ID => 26394, V1 => 1, V2 => 3),
            3 => array( ID => 49385, V1 => 1, V2 => 5),
            4 => array( ID => 70468, V1 => 1, V2 => 1),
            5 => array( ID => 50911, V1 => 1, V2 => 1),
            6 => array( ID => 74502, V1 => 1, V2 => 1));

echo "<pre>\r\n";
foreach($arr as $elm) {
    echo $elm[ID] . " " . $elm[V1] . " " . $elm[V2] . "<br>\r\n";
}
echo "</pre>\r\n";

function cmp($a, $b) {
    if($a[V1] == $b[V1]) {
        return $b[V2] - $a[V2];
    } else {
        return $b[V1] - $a[V1];
    }
}

usort($arr, "cmp");

echo "<pre>\r\n";
foreach($arr as $elm) {
    echo $elm[ID] . " " . $elm[V1] . " " . $elm[V2] . "<br>\r\n";
}
echo "</pre>\r\n";
?>
Avatar billede arne_v Ekspert
02. april 2009 - 21:51 #30
<?php
class Data {
    public $id;
    public $v1;
    public $v2;
    public function __construct($idarg, $v1arg, $v2arg) {
        $this->id = $idarg;
        $this->v1 = $v1arg;
        $this->v2 = $v2arg;
    }
}

$arr = array(new Data( 23006, 1, 3),
            new Data( 11258, 3, 1),
            new Data( 26394, 1, 3),
            new Data( 49385, 1, 5),
            new Data( 70468, 1, 1),
            new Data( 50911, 1, 1),
            new Data( 74502, 1, 1));

echo "<pre>\r\n";
foreach($arr as $elm) {
    echo $elm->id . " " . $elm->v1 . " " . $elm->v2 . "<br>\r\n";
}
echo "</pre>\r\n";

function cmp($a, $b) {
    if($a->v1 == $b->v1) {
        return $b->v2 - $a->v2;
    } else {
        return $b->v1 - $a->v1;
    }
}

usort($arr, "cmp");

echo "<pre>\r\n";
foreach($arr as $elm) {
    echo $elm->id . " " . $elm->v1 . " " . $elm->v2 . "<br>\r\n";
}
echo "</pre>\r\n";
?>
Avatar billede arne_v Ekspert
02. april 2009 - 21:51 #31
Det sidste kunne goeres noget paenere ved at bruge noget ordentlig encapsulation.

Men min hoved pointe er bare at [1] og [2] i cmp ikke er specielt laesbar kode.
Avatar billede hoppe11 Nybegynder
03. april 2009 - 11:23 #32
nej ok.. kan godt se hvad du mener med konstanter :)

har aldrig anvendt konstanter før, men kunne være man skulle overveje det

tak for eksemplerne
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester