PHP Array Inhalt zu einzelnen Strings?

FrazeColder

Lt. Commander
Registriert
Okt. 2013
Beiträge
1.721
Moin,

ich schon wieder :) - Ich habe nun schon 2 Stunden rumgetüftelt, bekomme es aber leider einfach nicht hin. Weder mit explode noch mit split...

Und zwar möchte ich ein Array, was aus mehreren Feldern besteht und Strings mit Wörtern beinhaltet zu einem Array zerlegen, was jeweils immer nur ein Wort als Wert aufnimmt. Obendrauf möchte ich dann noch die Anzahl der Wörter haben, die im Array gleich sind und somit das Array kürzen, das jedes Wort nur einmal vorkommt und mir dann noch als Zahl angegeben wird, wie oft es das Wort mal gab.

Kann mir da jemand helfen bzw. mir einen Denkanstoß geben?

MfG und Vielen Dank
 
Ist eingentlich simple:

Du deklarierst ein Array als Result-Array, danach loopst du über das ausgangs-array. Den Value explodest du anhand von Leerstellen. Die daraus resultierenden Werte fügst dann einzelnen als Array-Key zum eingangs erstellten Array hinzu. Dadurch hast du keine Doubletten. Da kannst du dann ja auch noch einen Counter mitlaufen lassen.
 
Ich werde mal schauen, was ich mit euren Hilfen anfangen kann.

Ich möchte aus diesem Ausgangsarray: ("das ist ein test", "frohe weihnachten", "test again", "vielen dank");
Das hier bekommen:

test 2
das 1
ist 1
ein 1
frohe 1
weihnachten 1
again 1
vielen 1
dank 1

also jedes Wort soll nur einmal in meinem neuen Array vorkommen, aber mit einer Zahl, die mir sagt, wie oft es das Wort im kompletten Ausgangsarray gab. Also einmal alles zerlegen und dann noch schauen, wie ich die "matchen" kann, damit der counter jeweils zu dem Wort eins hochgeht.
 
kommt halt drauf an, wie du den input tokenisieren willst. normalerweise auf das leerzeichen " " oder komplett alle whitespaces "\s+" (regex). dann ist das vorgehen wie folgt:

  1. erstelle ein ausgabearray
  2. iteriere ueber alle arrayeintraege (strings)
    1. tokenisiere den aktuellen string, iteriere ueber alle tokens
      1. pruefe, ob das ausgabearray bereits einen key hat, der dem aktuellen token gleicht
      2. nein? fuege ihn hinzu und setze ihn auf 1.
      3. ja? inkrementiere den eintrag um 1.
nachschlagelektuere waere dann:

iterieren: for, foreach
tokenisieren: explode, preg_split
key-existenz pruefen: array_key_exists oder ganz bloed if($arr[somekey])
 
Also ich habe es jetzt hinbekommen, das ganze zu einzelnen Strings zu zerlegen. Allerdings komme ich bei dem counter nicht weiter...
Sprich, wie oft es ein Wort gibt... Hat jemand eine Idee, woran das liegt?

Code:
<?php

// Enable Error Reporting
error_reporting (E_ALL);
ini_set ('display_errors', 'On');

if (file_exists('charts.xml')) {
    $xml = simplexml_load_file('charts.xml');

    $array = array();
    $i = 0;

    foreach ($xml->product as $product) {
        array_push($array, $product->name);
    }

    sort($array, SORT_NATURAL);


    foreach ($array as $value){
        //echo $value;
        //echo "<br/>";
    }

    $replacemenst = array(":", "-", ",", ";", "`", "#", "'", "´", "–", "!", "(", ")", ".", "@", "’");
    $newArray = array();

    foreach ($array as $value){
        $value = str_replace($replacemenst, "", $value);
        $array[$i] = $value;
        $i = $i + 1;
        //echo $value;
        //echo "<br/>";
    }

    //print_r($array);


    foreach ($array as $value){
        $temp = explode(" ", $value);
        $counter = count($temp);
        $j = 0;

        while($j < $counter){
            $temp[$j] = strtolower($temp[$j]);
            array_push($newArray, $temp[$j]);
            $j = $j + 1;
        }
    }

    $finalArray = array();
    $finalCounter = 0;
    $counterArray = count($newArray);

    while($finalCounter < $counterArray){
        $tempCounter = 0 ;
        foreach($newArray as $value){
            if($newArray[finalCounterl] == $value){
                $newArray[$tempCounter] = "";
                $tempFinal = 0;
                foreach($finalArray as $final){
                    if($value == $final){
                        $finalArray[$tempFinal][0] = $value;
                        $finalArray[$tempFinal][1] = $finalArray[$tempFinal][1] + 1;
                    }else{
                        $tmp[0] = $value;
                        $tmp[1] = 1;
                        array_push($finalArray, $tmp);
                    }
                    $tempFinal = $tempFinal + 1;
                }
            }
            $tempCounter = $tempCounter + 1;
        }
        $finalCounter = $finalCounter + 1;
    }

    // SHOW ALL DATA
    echo '<h1>Dump all data</h1><pre>';
    print_r($newArray);
    echo '</pre>';


} else {
    exit('Konnte charts.xml nicht oeffnen.');
}
?>
 
Um ganz ehrlich zu sein, ich verstehe nicht mal was dein While-Block da ueberhaupt macht. Oo
So wie bog es beschrieben hat funktioniert es wunderbar. Du brauchst eigentlich nur 2 foreach.

  • Ausgabe-Array anlegen
  • foreach ueber alle Produkte [foreach ($xml->product as $product)]
    • Produktname direkt bereinigen [str_replace($replacements, '', $product->name)]
    • Produktname explode() in Woerter auftrennen
    • foreach ueber alle Woerter
      • Mit array_key_exists() im Ausgabe-Array nachschauen ob Word vorhanden
      • Ja: hochzaehlen
      • Nein: hinzufuegen
 
Okay, das habe ich nun soweit. Allerdings komme ich beim letzten Schritt nicht weiter...
Ich muss ja zwei Werte speicher. Einmal das Word und einmal die Anzahl.

Wie kann ich nun aber, falls es schon existiert, die Anzahl hochzählen? - So wie ich das gemacht habe, geht das anscheinenden nicht...

Code:
//$newArray = Alle einzelnen Wörter
//$finalArray = Ausgaben Array. Soll so aussehen: Game 61 (Wort, Anzahl)

$finalArray = array();
    $counterArray = count($newArray);

    for($i = 0; $i < $counterArray; $i++){
        if(array_key_exists($newArray[$i], $finalArray)){
            $newArray[$i][1] = $newArray[$i][1] + 1;
            $newArray[$i] = "";
        }else{
            $temp = array();
            $temp[0] = $newArray[$i];
            $temp[1] = 1;
            array_push($finalArray, $temp);
        }
    }

Und Wenn wir schon dabei sind. Wie kann ich dann noch sagen, dass er mir das bitte so sortieren soll, das die Wörter mit der größten Anzahl oben stehen?
Damit ich mir das dann so ausgeben lassen kann! :)

Danke!
 
Ich habs so gemacht:
Code:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 'On');

$filename = 'FrazeColder.xml';

if (!file_exists($filename)) {
  exit('Konnte ' . $filename . ' nicht oeffnen.');
}

function CountWords($filename)
{
  if (!file_exists($filename)) {
    return [];
  }

  $xml = simplexml_load_file($filename);
  if ($xml === false) {
    return [];
  }

  $counters = [];
  $replace = [":", "-", ",", ";", "`", "#", "'", "´", "–", "!", "(", ")", ".", "@", "’"];

  foreach ($xml->product as $product) {
    $name = str_replace($replace, '', $product->name);

    $words = explode(' ', $name);

    foreach ($words as $word) {
      if (array_key_exists($word, $counters)) {
        $counters[$word]->counter++;
      } else {
        $counters[$word] = (object) ['word' => $word, 'counter' => 1];
      }
    }
  }

  usort($counters, function ($a, $b) {
    return $a->counter < $b->counter;
  });

  return $counters;
}

$counters = CountWords($filename);
print_r($counters);

Durch (object) ['word' => $word, 'counter' => 1] wird aus dem Array['word', 'counter'] ein Object erstellt. Dann kannst du einfach mit $counters[$word]->counter++ hochzaehlen.

Zum sortieren der Objekte verwende ich usort()
Code:
usort($counters, function ($a, $b) {
  return $a->counter < $b->counter;
});
 
Zuletzt bearbeitet:
Oh das koennte vielleicht an der PHP Version liegen. Welche verwendest du?
 
Jetzt. Abe rleider läuft es nur in der Console und in Chrome bekomme ich Bad Gateway... wieso?
 
Was steht in der Errorlog vom Webserver? Nutzt der die gleiche PHP Version?
 
Ich weiß leider nicht auf welchem Webserver das läuft. Läuft auf localhost. Wo ist denn da in Windows die Datei?
 
Wie verwendest du das ganze denn?
Ich habe das zum Beispiel als FrazeColder.php hier liegen und so aus der Console gestartet:
Code:
php -S 0.0.0.0:3000 FrazeColder.php
Im Browser rufe ich dann http://localhost:3000/ auf. Wie du das bei jetzt machst weiss ich nicht. :D
Hast du ueberhaupt einen Webserver lokal bei dir laufen? Apache z.B.?
 
Du fragst mich Sachen ahha... mit PHP und so habe ich noch nicht so viel Erfahrungen...

Ich habe PHPStorm (Student) und klick halt auf Play oben... Mehr nicht
 
<?php oben hinzugefuegt? Dateiname der XML angepasst? :D
Gibt doch sicher eine Console die etwas ausgibt sobald auf Play drueckst.
Ich kann hier jetzt nur raten :D
 
Zurück
Oben