Shuffle- teile aus mehrdimensionalen array


klausi89

Erfahrenes Mitglied
#1
Hallo ich wollte mal wissen ob es möglich ist aus einem mehrdimensionalen array nur bestimmte Teile zu mischen

PHP:
<?php
$mitarbeiter = array(
  array("link1", "http://www.link1.de"),
  array("link2", "http://www.link2.de"),
  array("link3 ", "http://www.link3.de")
);
Also ich würde gerne nur die links mischen ohne die urls geht das?

Danke schon mal
 

Sempervivum

Erfahrenes Mitglied
#2
Ich habe mal zwei Varianten entwickelt.
Basis für den shuffle-Algorithmus der zweiten ist dieses:
How can I shuffle an array?
Ich hoffe, ich habe es korrekt umgesetzt.
Interessant wäre zu untersuchen wie beide sich von der Performance her verhalten.
PHP:
    $mitarbeiter = array(
        array("link1", "http://www.link1.de"),
        array("link2", "http://www.link2.de"),
        array("link3", "http://www.link3.de"),
        array("link4", "http://www.link4.de"),
        array("link5", "http://www.link5.de")
      );

    // Mit vorgefertigten Funktionen
    $names = array_column($mitarbeiter, 0);
    shuffle($names);
    $mitarbeiter_shuffled = array_map(function($ma, $na) {
        $ma[0] = $na;
        return $ma;
    }, $mitarbeiter, $names);
    var_dump($mitarbeiter_shuffled);

    // Ausprogrammiert
    for ($i = count($mitarbeiter) - 1; $i > 0; $i--) {
        $j = rand(0, $i - 1);
        $x = $mitarbeiter[$i][0];
        $mitarbeiter[$i][0] = $mitarbeiter[$j][0];
        $mitarbeiter[$j][0] = $x;
    }
    var_dump($mitarbeiter);
 

klausi89

Erfahrenes Mitglied
#3
Klasse ich danke dir wie verrückt, es funktioniert genau wie ich mir das vorgestellt habe (y):)

Nun noch eine Frage welche Variante würdest du bevorzugen? mit Funktion oder ausprogrammiert...
 

Sempervivum

Erfahrenes Mitglied
#4
Das hängt davon ab, wie groß dieses Array ist. Sind es mehrere tausend Einträge, würde es sich lohnen, mal die Zeit zu messen, die gebraucht wird. Sind es wesentlich weniger, spielt die Laufzeit nicht so die große Rolle und ich bin unentschieden, welches ich bevorzugen würde.
Ich habe häufig die Erfahrung gemacht, dass die fertigen Funktionen von PHP performanter sind als etwas, das man selbst ausprogrammiert. In diesem Fall erfordern die fertigen jedoch drei Durchläufe während das Ausprogrammierte in einem erledigt ist.
Mal sehen, vielleicht findet jemand noch eine einfachere Möglichkeit.
 

klausi89

Erfahrenes Mitglied
#5
ok danke, hab nun trotzdem noch was....auf die einzelnen Teile im Array kann man jetzt so aber nicht mehr direkt zugreifen...das wird immer gemischt oder...also das ich gezielt einen link aus dem Array anspreche um die diese links ohne zu mischen vereinzelt nochmals auf der Seite verwenden kann, mein ziel ist sozusagen das ich nur eine Linkliste habe wo ich bei bedarf eben links entfernen oder hinzufügen kann, eben für das eine bräuchte ich die links gemischt und ich würde gerne auch einzeln auf das array zugreifen.

habs schon selbst gefunden, sry :cool: hab nochmal drüber nachgedacht und funktioniert danke dir

Gute Nacht ;)
 

klausi89

Erfahrenes Mitglied
#6
Guten Morgen, ich hab da doch noch mal ne Frage,

ich habe jetzt 10 links im array, auf der Webseite lasse ich immer 3 davon ausgeben, bei klick auf so einen Link öffnet sich ein Modal

HTML:
<ul class="list-unstyled">
            <li class="btn btn-block btn-outline-warning">
              <a data-toggle="modal" data-target="#step1"><?php echo $mitarbeiter_shuffled[0][0]; ?></a>
            </li>
            <li class="btn btn-block btn-outline-warning">
               <a data-toggle="modal" data-target="#step1"><?php echo $mitarbeiter_shuffled[1][0]; ?></a>
            </li>
            <li class="btn btn-block btn-outline-warning">
               <a data-toggle="modal" data-target="#step1"><?php echo $mitarbeiter_shuffled[2][0]; ?></a>
            </li>
          </ul>
nun möchte ich aber gerne das je nachdem welcher link aufgerufen wird auch die dazugehörige url dann angezeigt wird.

PHP:
if($linkliste_shuffled[0][0] === $arbeiter[0][0])
             {
              echo $arbeiter[0][1];
             }
usw.

nun funktioniert dies aber nur wenn der shuffled link auch der ist der zur url gehört, so müsste man ja für jeden schuffledlink([0][0], [1][0] usw.) alle links definieren. geht sowas auch einfacher zu lösen. weißt du das zufällig.

achso und damit du weißt warum da jetzt $arbeiter steht, ich habe den array $arbeiter genannt damit ich den array auch direkt ansprechen kann. und damit die mischfunktion von dir erhalten bleibt dann eben

PHP:
$mitarbeiter = $arbeiter;
 
Zuletzt bearbeitet:

Sempervivum

Erfahrenes Mitglied
#7
Das verstehe ich noch nicht richtig. Kannst Du es vielleicht auf die konkrete Anwendung bezogen etwas genauer erklären, wie es sich mit Mitarbeiter und Arbeiter verhält.
Oder würde es dir helfen, wenn man die Texte, die ich als name bezeichnet habe, sowohl in der originalen Reihenfolge als auch shuffled bereitstellt, d. h.:
Code:
$name_original = mitarbeiter[idx][0];
$name_shuffled = mitarbeiter[idx][2];
$link = mitarbeiter[idx][1];
 

klausi89

Erfahrenes Mitglied
#8
ok also ich habe mein Array,

Code:
$arbeiter = array(
        array("link1", "http://www.werbebanner1.com"),     
        array("link2", "http://www.werbebanner2.com"),
        array("link3", "http://www.werbebanner3.com"),
        array("link4", "http://www.werbebanner4.com"),
        array("link5", "http://www.werbebanner5.com"),                         
        array("link6", "http://www.werbebanner6.com"),
        array("link7", "http://www.werbebanner7.com"),
        array("link8", "http://www.werbebanner8.com"),
        array("link9", "http://www.werbebanner9.com"),
        array("link10", "http://www.werbebanner10.com")                       
      );
      
    
    $mitarbeiter = $arbeiter;
    // Mit vorgefertigten Funktionen
    $names = array_column($mitarbeiter, 0);
    shuffle($names);
    $mitarbeiter_shuffled = array_map(function($ma, $na) {
        $ma[0] = $na;
        return $ma;
    }, $mitarbeiter, $names);
auf der webseite werden wie gesagt 3 davon ausgewählt und angezeigt.

PHP:
echo $mitarbeiter_shuffled[0][0];
echo $mitarbeiter_shuffled[1][0];
echo $mitarbeiter_shuffled[2][0];
bei klick auf so einen link öffnet sich wie gesagt ein Modal dort sollte dann stehen, sie möchten link1 besuchen (bzw. link2, link3 eben welcher gemischt wurde) und dort soll eben wieder der entsprechende verweis übergeben werden und nach 10 sekunden weitergeleitet werden.

also z.bsp. wurde link5 gemischt, soll im modal dann auch zum http link von link5 weitergeleitet werden.

mit der If-bedingung funktioniert das zwar aber so wird das ja eine ewig lange sache.

also im modal hab ich dann dieses hinterlegt

PHP:
if($mitarbeiter_shuffled[0][0] === $arbeiter[0][0])
             {
              echo $arbeiter[0][1];
             }
if($mitarbeiter_shuffled[0][0] === $arbeiter[1][0])
             {
              echo $arbeiter[1][1];
             }
             usw.
            
             das würde dann ja ewig gehen

if($mitarbeiter_shuffled[0][0] === $arbeiter[9][0])
             {
              echo $arbeiter[9][1];
             }
nach diesem shema müsste das ja für
PHP:
$mitarbeiter_shuffled[0][0]
$mitarbeiter_shuffled[1][0]
$mitarbeiter_shuffled[2][0]
gemacht werden damit zu jedem link dann auch automatisch der richtige http link ausgewählt wird.
aber wenn der array mal größer wird wäre das doch eine riesen arbeit alles in if-bedingungen zu schreiben.

ich hoffe du weißt jetzt wie ich das meine.
 

Sempervivum

Erfahrenes Mitglied
#9
Nein, ich verstehe leider immer noch nur wenig, was Du da vorhast. Es wäre hilfreich, wenn Du beschreibst, was das in der realen Welt bedeutet, die Arbeiter/Mitarbeiter und die Links.
Aber ohne es zu verstehen, kann ich sagen, dass Du diese if-Abfragen sehr leicht in einer Schleife mit einer Funktion realisieren kannst:
PHP:
function getlink($idx) {
    $name = $mitarbeiter_shuffled[idx][0];
    foreach ($arbeiter as $arb) {
        if ($name === $arb[0]) return $arb[1];
    } 
}
Allerdings verstehe ich dann nicht, warum Du zunächst solch einen Aufwand treibst, um nur die Namen zu shuffeln, wenn Du hinterher wieder die originale Zuordnung heraus suchst?
 

Sempervivum

Erfahrenes Mitglied
#11
Die Funktion gibt auch nichts aus, sondern liefert nur den Wert zurück.Versuche dies:
echo getlink(1);
Wenn es dann nicht funktioniert, muss ich es in meiner Testdatei untersuchen.
 

klausi89

Erfahrenes Mitglied
#12
da werden leider nur lauter warning angezeigt

use of undefinid constant idx - warning
undefinid variable mitarbeiter_shuffled - notice
undefinid variable arbeiter - notice
invalid argument supplied for foreach() - warning

Puh da bin ich gerade überfragt.... sry muss erstmal auf Arbeit jez...schönen Tag noch ;)
 

Sempervivum

Erfahrenes Mitglied
#13
Das waren nur zwei Flüchtigkeitsfehler:
  • $ vor idx fehlte
  • globale Variablen müssen deklariert werden, damit sie in einer Funktion sichtbar sind
Dieses funktioniert:
Code:
    function getlink($idx) {
        global $mitarbeiter_shuffled, $arbeiter;
        $name = $mitarbeiter_shuffled[$idx][0];
        foreach ($arbeiter as $arb) {
            if ($name === $arb[0]) return $arb[1];
        }
    }
    echo getlink(0);
    echo getlink(1);
    echo getlink(2);
 

klausi89

Erfahrenes Mitglied
#15
Hallo ich wollte noch mal fragen ob man das data-target attribut irgendwie übergeben kann.

es gibt zwar themen dazu im internet aber die passen nicht ganz zu meinem beispiel

ich hab ein Modal (per Bootstrap4) das data-target hatte ich probiert so zu gestalten data-target="#modal<?php $id=1; ?>" usw.

und eben im Modal

wenn modal1 dann zeige getlink(0);
wenn modal2 dann zeige getlink(1);
usw.

leider funktioniert das so nicht...im Netz habe ich einiges gesehen das das nur mit javascript gehen würde. Ist das richtig?

Könnte mir jemand einen Tipp geben sonst müsste ich 9 Modals machen was ich nicht so schön finde und vorallem sehr auswendig für aktualisierungen.
 

Sempervivum

Erfahrenes Mitglied
#16
Ich kann mich erinnern, dieser Aufgabe schon begegnet zu sein. Es gibt dazu einige Anleitungen, z. B. hier bei Bootstrap direkt:
Modal
(der Abschnitt "Varying modal content ")
Und ja, offenbar geht das nur mit Javascript, jedenfalls, wenn man nur ein Modal haben will.