2017-08-07 420 views
-1

我使用一個文本文件作爲小數據庫,通過其內部價值命令字符串,並且每行有這樣的格式:需要幫助

3692|Giovanni|giojo982|0005405 
9797|Stefano|stefy734|45367 
2566|Marco|markkkk998|355647689 
4721|Roberto|robn88|809678741 

我需要對它們進行排序按字母順序維護其索引,如果可能的話。 目前,我正在使用此代碼,但在這種情況下,邏輯上它不再工作。

閱讀本文How can I sort arrays and data in PHP?我還沒找到類似於我的場景。 所以,我想知道...有解決方案嗎?

$db_friends = "db_friends.txt"; 
$dblines = file($db_friends); 

if(isset($_GET['A-Z'])) { 
    asort($dblines); 
} 
if(isset($_GET['Z-A'])) { 
    arsort($dblines); 
} 

foreach($dblines as $key => $profile) { 
    list($uni_id, $name_surname, $textnum_id, $num_id) = explode("|", $profile); 
    echo $name_surname; 
} 

<a href="./?A-Z">A-Z</a> 
<a href="./?Z-A">Z-A</a> 

我該如何解決?

+0

究竟你 「維護自己的指數」 是什麼意思?你的意思是每個字符串中的第一個數字? – GrumpyCrouton

+0

每個字符串的索引... [0] [1] [2] [3] – Devilix

+0

您對A-Z順序的期望是什麼? –

回答

3

我按字母順序假設您正嘗試按字母順序排列第二列中的名稱。問題是,asort()arsort()執行過於簡單的比較來處理您給他們的數據類型。他們只是將行看作字符串,並按第一列中的數字排序。解決這個問題的一種方法是在排序之前拆分行。

$db_friends = "db_friends.txt"; 
$dblines = file($db_friends); 

// split each line into an array 
$dblines = array_map(function($line){ 
    return explode('|', $line); 
}, $dblines); 

然後您可以更容易地按第二列排序。使用uasort(),您將維護索引關聯。

if (isset($_GET['A-Z'])) { 
    uasort($dblines, function(array $a, array $b) { 
     return strcmp($a[1], $b[1]); 
    }); 
} 

if (isset($_GET['Z-A'])) { 
    uasort($dblines, function(array $a, array $b) { 
     return strcmp($b[1], $a[1]); 
    }); 
} 

顯然,如果你做出的改變,你將不再需要爆炸,當你遍歷數組排序,因爲它是在第一步已經完成。

foreach ($dblines as $key => $profile) { 
    list($uni_id, $name_surname, $textnum_id, $num_id) = $profile; 
    echo $name_surname; 
} 
1

如果我明白你的問題,你可以試試這個功能:

function sortValuesKeepKey($lines) { 

     //declare arrays to be used temporarily 
     $idNumbers = array(); 
     $values = array(); 
     $return = array(); 

     //loop through each line and seperate the number at the beginning 
     //of the string from the values into 2 seperate arrays 
     foreach($lines as $line) { 
      $columns = explode("|", $line); 
      $id = array_shift($columns); 

      $idNumbers[] = $id; 
      $values[] = implode("|", $columns); 
     } 

     //sort the values without the numbers at the beginning 
     asort($values); 

     //loop through each value and readd the number originally at the beginning 
     //of the string 
     foreach($values as $key => $value) { 
      //use $key here to ensure your putting the right data back together. 
      $return[$key] = $idNumbers[$key]."|".$values[$key]; 
     } 

     //return finished product 
     return $return; 
    } 

只是通過它的線條作爲一個數組,它應該回到它下令正常。

0

如果您想通過name_surname的值進行排序,看看下面的代碼

$db_friends = "db_friends.txt"; 
$dblines = file($db_friends); 
// loop the lines 
foreach($dblines as $key => $profile) { 
    // explode each line with the delimiter 
    list($uni_id, $name_surname, $textnum_id, $num_id) = explode("|", $profile); 
    // create an array with name_surname as a key and the line as value 
    $array[$name_surname] = $profile; 
} 
// bases on the GET paramater sort the array. 
if(isset($_GET['A-Z'])) { 
    ksort($array); //sort acceding 
} 
if(isset($_GET['Z-A'])) { 
    krsort($array); // sort descending 
} 
// loop the sorted array 
foreach($array as $key => $value) { 
    echo $key; // display the name_surname. 
} 
+0

Downvoted,因爲這個答案不正確。它不保留OP所需的原始索引。 http://sandbox.onlinephpfunctions.com/code/69c08082864e45f4ca9fa7c08219fadb7bc596c6 – mickmackusa

1

可以避開一個uasort()調用的複雜性,如果你只是定位在爲了你的專欄要按字母順序排列它們。此方法還具有從左到右排列所有列數據的優點。這意味着,無論排序方向如何(asc或desc),我的方法將排序$rows[0],然後$row[1],然後$row[2],然後$row[3]

我也邏輯地結合了你的兩個if語句並將ASC設置爲默認排序方向。

代碼:(Demo

$txt=['9999|Marco|markkkk998|355647689','1|Marco|markkkk998|355647689','3692|Giovanni|giojo982|0005405','9797|Stefano|stefy734|45367','2566|Marco|markkkk998|355647689','4721|Roberto|robn88|809678741']; 

foreach($txt as $row){ 
    $values=explode('|',$row); 
    $rows[]=[$values[1],$values[0],$values[2],$values[3]]; // just reposition Name column to be first column 
} 
if(isset($_GET['Z-A'])) { 
    arsort($rows); // this will sort each column from Left-Right using Z-A 
}else{ 
    asort($rows); // (default) this will sort each column from Left-Right using A-Z 
} 
// var_export($rows); 
foreach($rows as $i=>$profile) { 
    echo "$i {$profile[0]}\n"; // name value 
} 

輸出:

2 Giovanni 
1 Marco 
4 Marco 
0 Marco 
5 Roberto 
3 Stefano 
+0

有趣,但我不能回顯名稱,例如... :(我需要創建另一個foreach循環? – Devilix

+0

@魔鬼是的,我的回答是就像所有其他人一樣,你需要在排序後再次循環,我已經更新了我的答案來顯示這個,對你的情況來說這可能是一個無用的功能,但是我的方法會將數據排序到一個列之外。在你的列表中有重複的名字,它會根據下一列的順序排列重複的命名行,然後是下一行等。 – mickmackusa