[英]How to sort a multidimensional array of columns by a specific column in PHP?
我在PHP文檔中發現了用於對數組“列”進行排序的函數“ array_multisort”。 他們提供了一個示例,其中用戶具有一個行數組,然后用戶必須將該行數組轉換為列數組。 在我的情況下,數組已經由列設置,例如:
tablearray
{
['Employee_ID'] = {0 => row1, 1 => row2, 2 => row3, 3 => row4}
['First_Name'] = {0 => row1, 1 => row2, 2 => row3, 3 => row4}
['LastName'] = {0 => row1, 1 => row2, 2 => row3, 3 =>row4}
}
我想按Employee_ID排序,我需要所有其他列遵循相同的順序。 我試過了:
array_multisort($tablearray['Employee_ID'], SORT_ASC);
但是,它僅對第一列進行排序(變成一團糟)。 該數組有10多個列,它根據搜索更改列名稱(列名稱是其鍵)。 在PHP的此函數的文檔中,提供的示例顯示,在將rows數組轉換為columns數組之后,我們應該使用原始數組作為與鍵匹配的第三個參數-我沒有“ original”數組要做比賽,因為我沒有改變任何東西。
謝謝。
一位用戶建議的所需輸出:
Original:
array
{
['Employee_ID'] = (1002, 4508, 0002, 1112)
['Business_Unit'] = ('UER', 'ABC', 'XYZ', 'EER')
['LastName'] = ('Smith', 'Vicente', 'Simpson', 'Thompson')
}
Sorted by Employee ID:
array
{
['Employee_ID'] = (0002, 1002, 1112, 4508)
['Business_Unit'] = ('XYZ', 'UER', 'EER', 'ABC')
['LastName'] = ('Simpson','Smith', 'Thompson', 'Vicente')
}
-我的原始數組是數據庫查詢輸出:
Array
(
[0] => Array
(
[Employee_ID] => 0000
[Supervisor_ID] => 00000
[Location_Descr] => somewhere
[Start_Date] => 06/03/2002
[Service_Date] => 06/03/2002
[Rehire_Date] => 00/00/00
[Business_Unit] => YYYY
[Job_Title] => Manager
[Email] => email@example.com
[Dept_Desc] => bla bla bla
[Employee_Name_LF] => Last, First
[Supervisor_Name_LF] => Last, First
[Term_Date] => 00/00/00
[Preferred_Name] => Someone
[Source] => Sheet2
)
)
還有幾行。 主要目的是將結果顯示為HTML表格並生成CSV文件。 我已經使用修改后的結構(我發布的第一個)進行了這些功能。 我認為處理這種結構會更容易...的確如此,但不幸的是並非如此。
array_multisort文檔( http://php.net/manual/en/function.array-multisort.php )建議將每一列分隔為一個單獨的數組。但是,如您所見,我有幾列(用戶可以選擇或多或少要在執行查詢之前顯示。。因此,我不能只在語句中列出所有它們)。
我願意更改所有內容,只是為了更好地使用代碼。
丑陋-如果格式化輸入表會容易得多。
$arr = array(
'Employee_ID' => array('1002', '4508', '0002', '1112'),
'Business_Unit' => array('UER', 'ABC', 'XYZ', 'EER'),
'LastName' => array('Smith', 'Vicente', 'Simpson', 'Thompson')
);
$employees = array();
foreach (range(0, sizeof($arr[current(array_keys($arr))]) - 1) as $k) {
$emp = array();
foreach ($arr as $col => $vals) {
$emp[$col] = $arr[$col][$k];
}
$employees[] = $emp;
}
$sort = array();
foreach ($employees as $k => $v) {
$sort[$k] = $v['Employee_ID'];
}
array_multisort($sort, SORT_ASC, $employees);
print_r($employees);
並放回原始格式:
$arr_sorted = array();
foreach (array_keys($arr) as $col) {
$arr_sorted[$col] = array();
foreach ($employees as $emp) {
$arr_sorted[$col][] = $emp[$col];
}
}
print_r($arr_sorted);
感謝您發布問題中的其他詳細信息,因為它們確實有助於您理解問題的意圖。
現在,您沒有告訴我們該桌子的外觀; 如果您希望員工每行一位,或每列一位。 要知道哪種至關重要。 通常,每條生產線只有一名員工,特別是如果要將其導出到CVS。 但是,我懷疑是您想要的后者。 否則,您將以過於復雜的方式進行處理。
以防萬一:正常的單行布局:
<?php
$db = new PDO();
// Defining the fields we need here, to avoid having too long a string for the query.
$fields = "e.employee_id, e.first_name, e.lastname, u.business_unit, s.email";
// Do the sorting in the database itself. Not only is this faster, but it
// is also a lot easier to sort it exactly as you'd like.
// Note that I don't use prepared statements here, as there is no user-input.
$query = <<<outSQL
SELECT {$Fields} FROM `unit` AS u
INNER JOIN `employee` AS e ON e.employee_id = u.unit_id
INNER JOIN `employee` AS s ON s.employee_id = u.supervisor_id
ORDER BY e.`employee_id`
outSQL;
$data = $db->query($query);
// Creating a printf() template for the output, to make the code easier to maintain.
$rowTemplate = <<<outHTML
<tr>
<td>%1\$d</td>
<td>%2\$s</td>
<td>%3\$s</td>
</tr>
outHTML;
// Generate the table template, using placeholders for where the data will be added..
$tableTemplate = <<<outHTML
<table>
<thead>
<tr>
<th>ID</th>
<th>First name</th>
<th>Last name</th>
</tr>
</thead>
<tbody>
%s
</tbody>
</table>
outHTML;
// Regular table output, one employee per line.
$temp = '';
foreach ($data as $e) {
// hs() is a shortcut function to htmlspecialchars (), to prevent against XSS.
$temp .= sprintf($rowTemplate, $e['employee_id'], hs($e['first_name']), hs($e['lastname']));
}
// Add the rows to the table, so that you can echo the completed product wherever you need.
$employeeTable = sprintf($tableTemplate, $temp);
如果您想每列執行一次,則它會變得更加復雜。 雖然,仍然比您的第一次嘗試容易一些。 :)
即是這樣的:
<?php
$db = new PDO();
// Defining the fields we need here, to avoid having too long a string for the query.
$fields = "employee_id, first_name, lastname";
// Do the sorting in the database itself. Not only is this faster, but it
// is also a lot easier to sort it exactly as you'd like.
// Note that I don't use prepared statements here, as there is no user-input.
$data = $db->query("SELECT {$Fields} FROM `employees` ORDER BY `employee_id`");
// We need to know how many columns we'll have. One per employee.
$columns = count ($data);
// Rows have a header in front of each line, and one td tag for each employee.
$rowTemplate = "\t\t<th>%s</th>\n".str_repeat("\t\t\t<td>%s</td>\n", $columns);
// Generate the table template, using placeholders for where the data will be added..
$tableTemplate = <<<outHTML
<table>
<tbody>
%s
</tbody>
</table>
outHTML;
// Reformat the array to give us the data per-column.
$temp = array ();
foreach ($data as $field => $e) {
// Since we've already sorted the data in the database we don't need to do any further sorting here.
// Also note that I'm doing the escaping here, seeing as this array will only be used for output.
$temp['Employee ID'][] = intval($e['employee_id']);
$temp['First name'][] = hs($e['first_name']);
$temp['Last name'][] = hs($e['lastname']);
}
// Now we do the same as in the above example.
$rows = '';
foreach ($temp as $label => $l) {
// We have the label as the first template variable to be added, so put it as the first element.
array_unshift($l, $label);
// Add the current row of items to the output, using the previously established template.
$rows = vprintf($rowTemplate, $l);
}
// Add the rows to the table, so that you can echo the completed product wherever you need.
$employeeTable = sprintf($tableTemplate, $temp);
PS:尚未測試代碼,但應該可以。
我遇到了他的問題,並且在許多煩惱之后,在php手冊頁的注釋中找到了一個非常不錯的解決方案-我現在有以下功能,可以在需要解決此類問題時使用。
function fnArrayOrderby(){
//function to sort a database type array of rows by the values in one or more column
//source http://php.net/manual/en/function.array-multisort.php - user notes
//example of use -> $sorted = fnArrayOrderby($data, 'volume', SORT_DESC, 'edition', SORT_ASC);
$args = func_get_args(); //Gets an array of the function's argument list (which can vary in length)
//echo "sorting ".$args[0]."<br>";
if (!isset($args[0])) { return;}
$data = array_shift($args); //Shift an element off the beginning of array
foreach ($args as $n => $field) {
if (is_string($field)) {
$tmp = array();
foreach ($data as $key => $row)
$tmp[$key] = $row[$field];
$args[$n] = $tmp;
}
}
$args[] = &$data;
call_user_func_array('array_multisort', $args);
return array_pop($args);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.