2017-08-07 403 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