Regina Schlauklug: Werte nach Teilstring aus Array fitern

Hallo,

in meinem einfachen PHP-Array stehen folgende Werte:

Array
(
    [0] => mueller_1444939602
    [1] => meier_1445366036
    [2] => meier_1445366108
    [3] => schulze_1444858516
    [4] => schulze_1445013037
    [5] => schulze_1445282747
    [6] => feuerstein_1445284323
    [7] => feuerstein_1445284604
    [8] => feuerstein_1445361774
)

Wie kann ich möglichst performant das Array nach allen Werten filtern, die z.Bsp. mit 'schulze' beginnen? Jedesmal komplett das Array als Schleife durchlaufen, wollte ich gern vermeiden.

Vielen Dank, Regina :-)

  1. Array
    (
        [0] => mueller_1444939602
        [1] => meier_1445366036
        [2] => meier_1445366108
        [3] => schulze_1444858516
        [4] => schulze_1445013037
        [5] => schulze_1445282747
        [6] => feuerstein_1445284323
        [7] => feuerstein_1445284604
        [8] => feuerstein_1445361774
    )
    
    $s = 'schulze';
    
    $treffer = array_filter($array, function ($value) { global $s; return $s === substr($value, 0, strlen($s)); });
    

    Funktioniert so, wie ich es möchte. Wenn es einen besseren/sinnvolleren Weg gibt, dann nur her damit.

    1. Liebe Regina,

      $treffer = array_filter($array, function ($value) { global $s; return $s === substr($value, 0, strlen($s)); });

      damit iterierst Du auch durch das ganze Array. Man sieht es nur nicht mehr so deutlich.

      Liebe Grüße,

      Felix Riesterer.

    2. $s = 'schulze';
      
      $treffer = array_filter($array, function ($value) { global $s; return $s === substr($value, 0, strlen($s)); });
      

      Kleiner Tipp am Rande: Mit der use-Klasel lassen sich globale Varialen in Closures vermeiden.

      $treffer = array_filter($array, function ($value) use ($s) { return $s === substr($value, 0, strlen($s)); });
      
  2. Liebe Regina,

    Array
    (
        [0] => mueller_1444939602
        [1] => meier_1445366036
        [2] => meier_1445366108
        [3] => schulze_1444858516
        [4] => schulze_1445013037
        [5] => schulze_1445282747
        [6] => feuerstein_1445284323
        [7] => feuerstein_1445284604
        [8] => feuerstein_1445361774
    )
    

    Du hast Werte, die aus Strings bestehen, wobei zuerst eine nicht festgelegte Menge an Buchstaben kommt, dann ein Unterstrich, und dann Ziffern. Da kann mit mit in_array() nichts anfangen. Du wirst um eine Schleife, die das komplette Array durchliest, nicht herumkommen.

    Vielleicht kannst Du aber bei der Erstellung des Arrays diese Struktur erzeugen?

    array(
        'mueller' => array(
            0 => mueller_1444939602
        ),
        'meier' => array(
            0 => 'meier_1445366036',
            1 => 'meier_1445366108'
        ),
        'schulze' => array(
            0 => 'schulze_1444858516',
            1 => 'schulze_1445013037',
            2 => 'schulze_1445282747'
        ),
        'feuerstein' => array(
            0 => 'feuerstein_1445284323',
            1 => 'feuerstein_1445284604',
            2 => 'feuerstein_1445361774'
        )
    )
    

    Nun hast Du in der übergeordneten Struktur alle Namen alleine, kannst also array_key_exists() aufrufen, und erhältst alle Einträge, die mit dem jeweiligen Namen anfangen.

    Liebe Grüße,

    Felix Riesterer.

    1. @@Felix Riesterer

      Vielleicht kannst Du aber bei der Erstellung des Arrays diese Struktur erzeugen?

      array(
          'mueller' => array(
              0 => mueller_1444939602
          ),
          'meier' => array(
              0 => 'meier_1445366036',
              1 => 'meier_1445366108'
          ),
          'schulze' => array(
              0 => 'schulze_1444858516',
              1 => 'schulze_1445013037',
              2 => 'schulze_1445282747'
          ),
          'feuerstein' => array(
              0 => 'feuerstein_1445284323',
              1 => 'feuerstein_1445284604',
              2 => 'feuerstein_1445361774'
          )
      )
      

      Dann eher diese:

      array(
          'mueller' => array(
              0 => '1444939602'
          ),
          'meier' =array(
              0 => '1445366036',
              1 => '1445366108'
          ),
          'schulze' => array(
              0 => '1444858516',
              1 => '1445013037',
              2 ='> 1445282747'
          ),
          'feuerstein' => array(
              0 => '1445284323',
              1 => '1445284604',
              2 => '1445361774'
          )
      )
      

      LLAP 🖖

      --
      Ist diese Antwort anstößig? Dann könnte sie nützlich sein.
      1. nach Perl umgesetzt, würde das untenstehenden Code ergeben, wobei innerhalb des 1. map{} von rechts aus gesehen, eine solche Substruktur entsteht. grep{} ist der Filter und im 2. map{} werden die Originalwerte wieder zusammengeführt.

        my @names = qw(
            mueller_1444939602
            meier_1445366036
            meier_1445366108
            schulze_1444858516
            schulze_1445013037
            schulze_1445282747
            feuerstein_1445284323
            feuerstein_1445284604
            feuerstein_1445361774
        );
        
        my @filtered = map{ $_->[0] } grep{ $_->[1][0] eq 'schulze' } map{ [$_, [split("_", $_)]  ] } @names;
        print Dumper \@filtered;
        
        # Dumper gibt aus:
        $VAR1 = [
                  'schulze_1444858516',
                  'schulze_1445013037',
                  'schulze_1445282747'
                ];
        
  3. Tach!

    Wie kann ich möglichst performant das Array nach allen Werten filtern, die z.Bsp. mit 'schulze' beginnen? Jedesmal komplett das Array als Schleife durchlaufen, wollte ich gern vermeiden.

    Nimm einfach die Lösung mit dem verständlichsten Code. Wenn das mit realistischen Datengrößen zufriedenstellend schnell ist, dann Haken dran.

    Du kannst natürlich auch einen Haufen Komplexität draufwerfen, um mit einem supertollen Algorithmus ein paar Millisekunden sparen, aber damit hast du mehr Aufwand als die Sache wert ist.

    dedlfix.

  4. Hallo und guten Morgen,

    Lies dich in das Thema Baumstrukturen ein Bau deine Datenstrukturen dementsprechend sinnvoll auf Trenne Suche/Volltextvergleich und vorherige "maschinelle" Umformatierung voneineander. Manchmal sind zwei einfache Programmschritte schneller als ein komplexer.

    in meinem einfachen PHP-Array stehen folgende Werte:

    Array
    (
        [0] => mueller_1444939602
        [1] => meier_1445366036
        [2] => meier_1445366108
        [3] => schulze_1444858516
        [4] => schulze_1445013037
        [5] => schulze_1445282747
        [6] => feuerstein_1445284323
        [7] => feuerstein_1445284604
        [8] => feuerstein_1445361774
    )
    

    Wie kann ich möglichst performant das Array nach allen Werten filtern, die z.Bsp. mit 'schulze' beginnen? Jedesmal komplett das Array als Schleife durchlaufen, wollte ich gern vermeiden.

    Vielen Dank, Regina :-)

    Grüße
    TS

    --
    es wachse der Freifunk
    https://harz.freifunk.net