2016-06-26 5 views
0

Ich habe drei verschiedene Textdateien analysiert:Wie nach zwei Werten dann ein Feld von ASC in einem Array mit usort() in PHP?

space.txt

Kournikova Anna F F 6-3-1975 Red 
Hingis Martina M F 4-2-1979 Green 
Seles Monica H F 12-2-197 

comma.txt

Abercrombie, Neil, Male, Tan, 2/13/1943 
Bishop, Timothy, Male, Yellow, 4/23/1967 
Kelly, Sue, Female, Pink, 7/12/1959 

pipe.txt

Smith | Steve | D | M | Red | 3-3-1985 
Bonk | Radek | S | M | Green | 6-3-1975 
Bouillon | Francis | G | M | Blue | 6-3-1975 

ich den folgenden Code verwendet parse alle Dateien in ein Array .............

<?php 

    $space_txt = './data/input/space.txt'; 
    $comma_txt = './data/input/comma.txt'; 
    $pipe_txt = './data/input/pipe.txt'; 

    $parsed_space_data = file_get_contents($space_txt); 
    $parsed_comma_data = file_get_contents($comma_txt); 
    $parsed_pipe_data = file_get_contents($pipe_txt); 



    $space_array = myExpldeLoopFunc("space"," ", $parsed_space_data); 
    $comma_array = myExpldeLoopFunc("comma",",", $parsed_comma_data); 
    $pipe_array = myExpldeLoopFunc("pipe"," | ", $parsed_pipe_data); 


    $finalArray = array_merge($space_array, $comma_array, $pipe_array); 


    function changeGender($gender) { 

     if($gender === 'F') { 
      return str_replace('F', 'Female', $gender); 
     } 

     elseif($gender === 'M') { 
      return str_replace('M', 'Male', $gender); 
     } 
    } 

    function normalizeDate($date) { 
     return str_replace('-', '/', $date); 
    } 









    function myExpldeLoopFunc($name, $sep, $data) { 

     $parsedData = explode("\r", $data); 




     $arr = []; 
     foreach ($parsedData as $data) { 
      $data_arr = explode($sep, $data); 





      if($name == 'space'){ 

       $arr[] = [ 
        "last_name" => $data_arr[0], 
        "first_name" => $data_arr[1], 
        // "middle_initial" => $data_arr[2], 
        "gender" => changeGender($data_arr[3]), 
        "date_of_birth" => normalizeDate($data_arr[4]), 
        "favorite_color" => $data_arr[5] 



       ]; 








      } 

       elseif($name == 'comma') { 
        $arr[] = [ 
        "last_name" => $data_arr[0], 
        "first_name" => $data_arr[1], 
        "gender" => $data_arr[2], 
        "date_of_birth" => normalizeDate($data_arr[4]), 
        "favorite_color" => $data_arr[3] 

        ]; 
       } 

      elseif ($name == 'pipe') { 
        $arr[] = [ 
        "last_name" => $data_arr[0], 
        "first_name" => $data_arr[1], 
        // "middle_initial" => $data_arr[2], 
        "gender" => changeGender($data_arr[3]), 
        "date_of_birth" => normalizeDate($data_arr[5]), 
        "favorite_color" => $data_arr[4] 



       ]; 


      } 





    } 



    return $arr; 







     } 








for ($i=0; $i < count($finalArray); $i++) { 


foreach ($finalArray as $key => $row) { 
$gender[$key] = $row['gender']; 
$last_name[$key] = $row['last_name']; 
} 

array_multisort($gender, SORT_ASC, $last_name, SORT_ASC, $finalArray); 

echo join(' ', $finalArray[$i]) . '<br>'; 


    } 

var_dump($finalArray); 






?> 

Jetzt habe ich folgendes Array ...........

array (size=9) 
    0 => 
    array (size=5) 
     'last_name' => string 'Kournikova' (length=10) 
     'first_name' => string 'Anna' (length=4) 
     'gender' => string 'Female' (length=6) 
     'date_of_birth' => string '6/3/1975' (length=8) 
     'favorite_color' => string 'Red' (length=3) 
    1 => 
    array (size=5) 
     'last_name' => string ' 
Hingis' (length=7) 
     'first_name' => string 'Martina' (length=7) 
     'gender' => string 'Female' (length=6) 
     'date_of_birth' => string '4/2/1979' (length=8) 
     'favorite_color' => string 'Green' (length=5) 
    2 => 
    array (size=5) 
     'last_name' => string ' 
Seles' (length=6) 
     'first_name' => string 'Monica' (length=6) 
     'gender' => string 'Female' (length=6) 
     'date_of_birth' => string '12/2/1973' (length=9) 
     'favorite_color' => string 'Black' (length=5) 
    3 => 
    array (size=5) 
     'last_name' => string 'Abercrombie' (length=11) 
     'first_name' => string ' Neil' (length=5) 
     'gender' => string ' Male' (length=5) 
     'date_of_birth' => string ' 2/13/1943' (length=10) 
     'favorite_color' => string ' Tan' (length=4) 
    4 => 
    array (size=5) 
     'last_name' => string ' 
Bishop' (length=7) 
     'first_name' => string ' Timothy' (length=8) 
     'gender' => string ' Male' (length=5) 
     'date_of_birth' => string ' 4/23/1967' (length=10) 
     'favorite_color' => string ' Yellow' (length=7) 
    5 => 
    array (size=5) 
     'last_name' => string ' 
Kelly' (length=6) 
     'first_name' => string ' Sue' (length=4) 
     'gender' => string ' Female' (length=7) 
     'date_of_birth' => string ' 7/12/1959' (length=10) 
     'favorite_color' => string ' Pink' (length=5) 
    6 => 
    array (size=5) 
     'last_name' => string 'Smith' (length=5) 
     'first_name' => string 'Steve' (length=5) 
     'gender' => string 'Male' (length=4) 
     'date_of_birth' => string '3/3/1985' (length=8) 
     'favorite_color' => string 'Red' (length=3) 
    7 => 
    array (size=5) 
     'last_name' => string ' 
Bonk' (length=5) 
     'first_name' => string 'Radek' (length=5) 
     'gender' => string 'Male' (length=4) 
     'date_of_birth' => string '6/3/1975' (length=8) 
     'favorite_color' => string 'Green' (length=5) 
    8 => 
    array (size=5) 
     'last_name' => string ' 
Bouillon' (length=9) 
     'first_name' => string 'Francis' (length=7) 
     'gender' => string 'Male' (length=4) 
     'date_of_birth' => string '6/3/1975' (length=8) 
     'favorite_color' => string ' 

Blue' (length=4) 

So Far die Ausgabe ........

Kelly Sue Female 7/12/1959 Pink 
Bishop Timothy Male 4/23/1967 Yellow 
Abercrombie Neil Male 2/13/1943 Tan 
Hingis Martina Female 4/2/1979 Green 
Seles Monica Female 12/2/1973 Black 
Kournikova Anna Female 6/3/1975 Red 
Bonk Radek Male 6/3/1975 Green 
Bouillon Francis Male 6/3/1975 Blue 
Smith Steve Male 3/3/1985 Red 

ich möchte das Array sortieren, indem Frauen dann Männlich, dann durch LAST_NAME asc ........

Hingis Martina Female 4/2/1979 Green 
Kelly Sue Female 7/12/1959 Pink 
Kournikova Anna Female 6/3/1975 Red 
Seles Monica Female 12/2/1973 Black 
Abercrombie Neil Male 2/13/1943 Tan 
Bishop Timothy Male 4/23/1967 Yellow 
Bonk Radek Male 6/3/1975 Green 
Bouillon Francis Male 6/3/1975 Blue 
Smith Steve Male 3/3/1985 Red 

ich auch versucht ......

function sortBy($field, &$array, $direction = 'asc') { 
usort($array, create_function(' 
$a, $b', ' $a = $a["' . $field . '"]; 
$b = $b["' . $field . '"]; 
if ($a == $b) { 
return 0; 
} 
return ($a ' . ($direction == 'desc' ? '>' : '<') .' $b) ? -1 : 1; ')); 
return true; 
} 

for ($i=0; $i < count($finalArray); $i++) { 
sortBy('gender', $finalArray); 
sortBy('last_name', $finalArray); 
echo join(' ', $finalArray[$i]) . '<br>'; 
} 

Ich habe versucht, array_multisort(), usort(), sort(), asort(), und ich konnte immer noch nicht die Ergebnisse produzieren ich wollte. Mit welcher Lösung lässt sich das Ergebnis erzielen?

+1

'usort' ist immer noch Ihre Lösung. Zeigen Sie, was Sie mit ihm versucht –

+0

'Funktion sortBy ($ Feld & $ array, $ direction = 'ASC') { \t usort ($ array, create_function ('$ a, $ b', ' \t \t $ a = $ a [ " '$ Feld.. ' "]; \t \t $ $ b = b ["' $ Feld..'"]; \t \t if ($ a == $ b) \t \t { \t \t \t return 0; \t \t} \t \t Rückgabe ($ a '. ($ direction == 'desc'? '>': '<'). ' $ b)? -1: 1; \t ')); \t Rückkehr wahr; } '' für ($ i = 0; $ i '; \t \t \t} ' –

+3

Bearbeiten Sie Ihre Frage und fügen Sie das hinzu, anstatt es auf einen Kommentar zu setzen! –

Antwort

0

Die wichtigsten Punkte im Code:

  • Sie verteilen in \r: es besser ist, durch \n aufzuspalten, die auf allen Plattformen funktioniert. Aber da ein Zeilenvorschub \r\n sein kann, müssen Sie auch dieses andere Zeichen entfernen. Dies können Sie mit trim() tun. Also würde ich vorschlagen, trim() auf alle Werte anzuwenden.
  • Die Funktion changeGender sieht seltsam aus. Sie können all dies mit: return $gender === 'F' ? 'Female' : 'Male'.
  • Sie können auch leere Zeilen in Ihrer Eingabe überspringen.
  • Sie sortieren in einer Schleife auf Ihrem Array, das ist falsch. Diese äußere Schleife sollte entfernt werden. Wenn Sie die Daten auflisten möchten, verschieben Sie die Sortierung.

Der korrigierte Code (und auch schön gegliederte) folgt mit meinen Kommentaren als //** markiert:

$space_txt = './data/input/space.txt'; 
$comma_txt = './data/input/comma.txt'; 
$pipe_txt = './data/input/pipe.txt'; 

$parsed_space_data = file_get_contents($space_txt); 
$parsed_comma_data = file_get_contents($comma_txt); 
$parsed_pipe_data = file_get_contents($pipe_txt); 

$space_array = myExpldeLoopFunc("space", " ", $parsed_space_data); 
$comma_array = myExpldeLoopFunc("comma", ",", $parsed_comma_data); 
$pipe_array = myExpldeLoopFunc("pipe", " | ", $parsed_pipe_data); 

$finalArray = array_merge($space_array, $comma_array, $pipe_array); 

function changeGender($gender) { 
    return $gender === 'F' ? 'Female' : 'Male'; //** This is more straightforward 
} 

function normalizeDate($date) { 
    return str_replace('-', '/', $date); 
} 

function myExpldeLoopFunc($name, $sep, $data) { 
    $parsedData = explode("\n", $data); //** use "\n" instead of "\r" 
    $arr = []; 
    foreach ($parsedData as $data) { 
     if ($data === "") continue; //** skip empty lines 
     $data_arr = explode($sep, $data); 
     if($name == 'space'){ 
      $arr[] = [ 
       "last_name" => trim($data_arr[0]), //** trim all elements (also removes "\r") 
       "first_name" => trim($data_arr[1]), 
       // "middle_initial" => trim($data_arr[2]), 
       "gender" => changeGender(trim($data_arr[3])), 
       "date_of_birth" => normalizeDate(trim($data_arr[4])), 
       "favorite_color" => trim($data_arr[5]) 
      ]; 
     } elseif($name == 'comma') { 
      $arr[] = [ 
       "last_name" => trim($data_arr[0]), 
       "first_name" => trim($data_arr[1]), 
       "gender" => trim($data_arr[2]), 
       "date_of_birth" => normalizeDate(trim($data_arr[4])), 
       "favorite_color" => trim($data_arr[3]) 
      ]; 
     } elseif ($name == 'pipe') { 
      $arr[] = [ 
       "last_name" => trim($data_arr[0]), 
       "first_name" => trim($data_arr[1]), 
       // "middle_initial" => trim($data_arr[2]), 
       "gender" => changeGender(trim($data_arr[3])), 
       "date_of_birth" => normalizeDate(trim($data_arr[5])), 
       "favorite_color" => trim($data_arr[4]) 
      ]; 
     } 
    } 
    return $arr; 
} 

//** Removed the bad for-loop that appeared here. 
foreach ($finalArray as $key => $row) { 
    $gender[$key] = $row['gender']; 
    $last_name[$key] = $row['last_name']; 
} 
array_multisort($gender, SORT_ASC, $last_name, SORT_ASC, $finalArray); 

//** Output in a loop, but leave the above sorting out of it 
foreach ($finalArray as $row) { 
    echo join(' ', $row) . "<br>\n"; 
} 

print_r($finalArray); 

Sehen Sie es auf eval.in laufen, die die Beispieldaten verwendet, die Sie zur Verfügung gestellt.

Die Reihenfolge ist wie gewünscht.

+0

Der changGender() funktioniert wirklich –

+0

Ja, aber es sieht komisch aus. Es ist unnötig kompliziert. – trincot

+0

Ich verstehe, was Sie sagen, aber solange es funktioniert. Ich werde deinen vorgeschlagenen Code versuchen. –

1

Ok, ich gebe ein Beispiel mit zwei Kriterien, aber es ist nicht getestet auf Ihre Daten. Die folgende Funktion compare() empfängt zwei zu vergleichende Arrays. Wie geht das? Jedes Array enthält im Beispiel zwei Zahlen. Zuerst sortieren wir die Nummer mit Schlüssel = 0 und dann die Nummer mit Schlüssel = 1. Ihre Schlüssel sind natürlich unterschiedlich.

function compare($array1,$array2) 
{ 
    // numbers at key 0 are equal 
    if ($array1[0] == $array2[0]) 
    { 
    // so we look at key 1. 
    if ($array1[1] == $array2[1]) return 0; 
    return ($array1[1] < $array2[1]) ? -1 : 1; 
    } 
    return ($array1[0] < $array2[0]) ? -1 : 1; 
} 

$a = [[1,2],[3,4],[5,4],[4,2],[1,8]]; 

usort($a,'compare'); 

foreach ($a as $key => $value) 
{ 
    echo "<pre>$key: ".print_r($value,TRUE)."\n</pre>"; 
} 

Alles, was Sie tun müssen, ist dies an Ihren Fall anzupassen.

Dies sortiert zwei Werte in einem Array, beide, wie Sie es nennen würden, aufsteigend. Ändern Sie einfach die < zu >, wenn Sie eine von ihnen in der Reihenfolge wünschen. Die hier verwendeten Schlüssel sind 0 und 1, Ihre Schlüssel sind wie gender und last_name.

Einige Werte können nicht mit dem Vergleichsoperator < verglichen werden, Sie müssten also etwas anderes verwenden. Im Fall der last_name möchten Sie vielleicht strcasecmp() verwenden.

+0

Bisher wurden einige der Werte dupliziert. Ich habe 'gender' und' last_name' verwendet, aber '$ finalArray' als $ a –

+0

verwendet. Hier sind die Ergebnisse ............ 'Smith Steve Männlich 1985.03.03 Red Abercrombie Neil Männlich 1943.02.13 Tan Smith Steve Männlich 1985.03.03 Red Abercrombie Neil Männlich 1943.02.13 Tan Bischof Timothy Male 4/23/1967 Yellow Bonk Radek Männlich 1975.06.03 Grün Kournikova Anna Frau 1975.06.03 Red Bonk Radek Männlich 1975.06.03 Grün Kournikova Anna Frau 1975.06.03 Red' –

+0

Das sieht nicht sehr sortiert für mich. –

Verwandte Themen