Array Optimierung

  • Themenstarter Themenstarter scherlomatic
  • Beginndatum Beginndatum
S

scherlomatic

Hallo!

Rätsel jetzt schon Stunden an einer optimalen Lösung, hoffe ihr könnt mir mal wieder weiterhelfen.


Ausgangslage:
Ich hab mehrere Files (3) die folgende Werte im csv-Format enthalten.
customer_id;type;country;track
300001;1;DE;1
....
Was die einzelnen Werte bedeutet ist jetzt nicht ausschlaggebend, allerdings bräucht ich ein quasi UNIQUE auf customer_id, type und track.

Einlesen:
PHP:
$what = array('click', 'domain', 'view');
foreach ($what as $name) {
  $file = fopen($filename, 'r');
  while(($line = fgetcsv($file, null, ';')) !== FALSE) { .... }

Verarbeiten:
Und hier gibts nun mein Problem, wie les ich die Datei korrekt ein, damit pro Kunden_id && Type && Track nur eine "Zeile" angelegt wird und ZUSÄTZLICH ein Counter mitgeführt wird, der immer um 1 erhöht wird, wenn der Eintrag schon im Array ist.

Hoffe soweit ist alles klar.
Danach schreib ich halt alles in die Datenbank, was aber kein Problem mehr sein sollte.

Ziel ist halt, dass ich so wenig wie möglich Datenbankzugriffe habe.

Thx Stefan
 
Moin Stefan,

country soll dabei nicht berücksichtigt werden(bei dem "UNIQUE")?

Falls doch, könntest du die ganzen Zeilen erstmal als String einlesen, und die Anzahl der Vorkommen per array_count_values() ermitteln.

Aus dem Ergebnis erstellst du dann den benötigten Array, indem du die keys anhand ; splittest und um den value erweiterst.
 
Einen Schlüssel bilden und mit dem prüfen
PHP:
    define('CUSTOMER_ID', 0);
    define('TYPE', 1);

    $myData = array();
    while(($line = fgetcsv($file, null, ';')) !== FALSE) {
        
        $key = "{$line[CUSTOMER_ID]}#{$line[TYPE]}"; 
        
        if (!array_key_exists($key, $myData)){
            $myData[$key] = $line;
        }
    }
 
@sven
Stimmt, Country sollte auch ein unique sein.
Danke für den Hinweis

@yaslaw
Werd gleich mal versuchen, deinen Lösungsansatz umzusetzen. Find es persönlich zwar nicht grad schön, wenn dann alle 4 Werte als Key, nur durch einen Delimiter getrennt, gespeichert werden. Aber wird wohl die einzige vernünftige Lösung sein.


Lg Stefan
 
So hab jetzt soweit implementiert, allerdings fehlt noch eine kleine Schönheitskorrektur. Hier mal der Code:

PHP:
while(($line = fgetcsv($file, null, ';')) !== FALSE) {
  $key = "{$line[0]}#{$line[1]}#{$line[2]}#{$line[3]}";
  if (!array_key_exists($key, $data) ) {
    $data[$key] = $line;
    $data[$key][$name] = 1;
  } elseif(false) {
    //TODO: wenn $name in jeeweiligen array mit key nicht vorhanden anlgen
    //$data[$key][$name] = 1;
  } else {
    @$data[$key][$name] += 1;
  }
}

Wie schon vermuten lässt, beim elseif fehlt mir noch die Condition, es funktioniert zwar auch so, allerrdings bringt mir der else Zweig (ohne @) eine Warnung, was aber nix am ergebnis ändert.

Lg Stefan
 
Was ist $name? Wenn du das Feld namens 'name' meinst, dann solltest du es auch als String übergeben.

PHP:
$data[$key]['name'] = 1;

Nachtrag:
Oh, im ersten Posting sehe ich $name. Also ein Inhalt des arrays...

Kannst du mal den ganzen Code mit der äusseren Schleife posten? Hab da eineige Ideen..
 
Zuletzt bearbeitet:
Sorry für die Verwirrung, $name gibt folgende 3 Strings in einer foreach Schleife retour: 'click', 'domain', 'view'

Hoffe jetzt ist es klar, sonst kann ich auch gern mal den kompletten Code posten, ist aber ein Symfony Projekt.

Lg Stefan
 
Poste den Code mit der Schleife
PHP:
$what = array('click', 'domain', 'view');
foreach ($what as $name) { 
...
}
 
PHP:
$what = array('click', 'domain', 'view');
foreach ($what as $name)
		{
			$filename = 'log/statistic_' . $name . '_' . $date . '.log';

			if(($file = fopen($filename, 'r')) === FALSE)
			{
				printf("Konnte Datei nicht oeffnen: %s",$filename);
			}
			else
			{
				while(($line = fgetcsv($file, null, ';')) !== FALSE)
				{
					$key = "{$line[0]}#{$line[1]}#{$line[2]}#{$line[3]}";

					if (!array_key_exists($key, $data) )
					{
						$data[$key] = $line;
						$data[$key][$name] = 1;
					}
					elseif(false)
					{
						//TODO: wenn $name in jeeweiligen array mit key nicht vorhanden anlgen
						//$data[$key][$name] = 1;
					}
					else
					{
						@$data[$key][$name] += 1;
					}
				}

				fclose($file);
			}
		}
 
AM Anfang der ersten foreach-Schlaufe solltest du $data zurücksetzen
PHP:
$data=array();

oder $data um die Ebene deiner ersten Schleife erweitern
PHP:
if (!array_key_exists($key, $data[$name]) )
                    {
                        $data[$name][$key] = $line;
                        $data[$name][$key][$name] = 1;
                    }

Den Rest schau ich mir morgen an
 
Zurück