Малый алгоритм сортировки в php

Это должен быть довольно простой алгоритм, но я просто не могу обойти его.

У меня есть несколько массивов в алфавитном порядке

[0] => Array ( [0] => a [1] => b [2] => c ) 

и, например,

 [0] => Array ( [0] => a [1] => b [2] => c [3] => d ) 

и мне нужно отсортировать их по строкам. Например:

Я должен получить таблицу с тремя столбцами и количеством строк, которые она может получить, и она должна быть в алфавитном порядке.

Вот пример: Первый массив должен быть преобразован в

 [0] => Array ( [0] => Array ( [0] => a [1] => b [2] => c ) ) 

Но второй должен быть таким же

 [1] => Array ( [0] => Array ( [0] => a [1] => c [2] => d ) [1] => Array ( [0] => b ) ) 

Я пишу это в php , поэтому, если кто-то может помочь, я буду очень благодарен.

UPD: Пример кода:

 function sortAsOrdered( array $categories ) { foreach ( $categories as $groupId => $group ) { $regroupMenuItems = array(); $limit = count( $group ); $rows = ceil( $limit / 3 ); for ( $i = 0; $i < $rows; ++$i ) { $jumper = 0; for ( $j = 0; $j < 3; $j++ ) { if ( 0 == $jumper ) { $jumper = $i; } if ( isset( $group[ $jumper ] ) ) { $regroupMenuItems[ $i ][ $j ] = $group[ $jumper ]; } $jumper = $jumper + $rows; } } $categories[ $groupId ] = $regroupMenuItems; } return $categories; } 

Ребята, я решил это. Здесь вы можете увидеть мой алгоритм http://pastebin.com/xe2yjhYW . Но не грустите, ваша помощь не пойдет напрасно. Я, вероятно, поместит награду только для тех, кто помог мне в этом диалоговом алгоритме.

Парни благодарны еще раз. Твои мысли заставляли меня думать иначе.

Solutions Collecting From Web of "Малый алгоритм сортировки в php"

array_chunk () wold были решением, но поскольку вы хотите, чтобы он был специально отсортирован, это не сильно вам помогло.

Итак, вот мои пять центов:

 function array_chunk_vertical($input, $size_max) { $chunks = array(); $chunk_count = ceil(count($input) / $size_max); $chunk_index = 0; foreach ($input as $key => $value) { $chunks[$chunk_index][$key] = $value; if (++$chunk_index == $chunk_count) { $chunk_index = 0; } } return $chunks; } $array = array('a', 'b', 'c', 'd', 'e', 'f'); var_dump(array_chunk_vertical($array, 2)); 

Что даст вам:

 array 0 => array 0 => string 'a' (length=1) 3 => string 'd' (length=1) 1 => array 1 => string 'b' (length=1) 4 => string 'e' (length=1) 2 => array 2 => string 'c' (length=1) 5 => string 'f' (length=1) 

Недостатком этой функции является то, что вы можете только указать максимальное количество элементов в куске, а затем равномерно делить массив на куски. Итак, для [4] и max_size 3 вы получите [2,2] в отличие от ожидаемого [3,1].

 <?php $five_el = array('a', 'b', 'c', 'd', 'e'); $two_el = array('a', 'b'); $three_el = array('a', 'b', 'c'); $six_el = array('a', 'b', 'c', 'd', 'e', 'f'); function multid($sorted_array) { $mulidarray = array(); $row = 0; $column = 0; foreach ($sorted_array as $value) { if ($column == 3) { $row++; } $column++; if (!isset($mulidarray[$row])) { $mulidarray[$row] = array(); } $multidarray[$row][] = $value; } return $multidarray; } var_dump(multid($five_el)); var_dump(multid($two_el)); var_dump(multid($three_el)); var_dump(multid($six_el)); 

array_chunk – естественный первый подход к проблеме, но он не будет делать то, что вам нужно. Если решение предоставляется таким образом, вам необходимо либо реструктурировать результирующий массив, либо реструктурировать входные данные перед его обработкой, как показано ниже:

 $input = range('a', 'k'); // arbitrary $columns = 3; // configure this $rows = ceil(count($input) / $columns); // fugly, but this way it works without declaring a function // and also in PHP < 5.3 (on 5.3 you'd use a lambda instead) $order = create_function('$i', '$row = (int)($i / '.$rows.');'. '$col = $i % '.$rows.';'. 'return $col * ('.$columns.' + 1) + $row;'); // $order is designed to get the index of an item in the original array, // and produce the index that item would have if the items appeared in // column-major order instead of row-major as they appear now $array = array_map($order, array_keys($input)); // replace the old keys with the new ones $array = array_combine($array, $input); // sort based on the new keys; this will effectively transpose the matrix, // if it were already structured as a matrix instead of a single-dimensional array ksort($array); // done! $array = array_chunk($array, $columns); print_r($array); 

Смотрите в действии .

Посмотрим, будет ли это ближе к знаку

 function splitVerticalArrayIntoColumns($aInput, $iNumberOfColumns) { //output array $aOutput = array(); //the total length of the input array $iInputLength = count($aInput); //the number of rows will be ceil($iInputLength / $iNumberOfColumns) $iNumRows = ceil($iInputLength / $iNumberOfColumns); for($iInputIndex = 0; $iInputIndex < $iInputLength; $iInputIndex++) { $iCurrentRow = $iInputIndex % $iNumRows; $aOutput[$iCurrentRow][] = $aInput[$iInputIndex]; } //return return $aOutput; } 

Который – при запуске таким образом:

 $aList = array("a", "e", "d", "b", "c"); echo 'array("a", "e", "d", "b", "c")' . "\n\n"; print_r(splitVerticalArrayIntoColumns($aList, 3)); 

дает:

 array("a", "e", "d", "b", "c") Array ( [0] => Array ( [0] => a [1] => d [2] => c ) [1] => Array ( [0] => e [1] => b ) ) 

Это еще не сортировка каждой строки, но это то, что вам нужно?



begin facepalm edit

… или, конечно, array_chunk($aList, 3) после того, как вы его отсортировали O_o

http://uk3.php.net/manual/en/function.array-chunk.php

Я оставлю все ниже для справки или что-то еще – я полностью забыл о array_chunk ()

end facepalm edit


Я бы использовал modulo в цикле, где вы подсчитываете индекс массива (после сортировки массива) – например, если вы пытаетесь разбить массив на 3 "столбца", вы можете попробовать что-то вроде:

 if($iIndex % 3 == 0) { //... create a new array } else { //... add to an existing array } 

Пример кода EDIT:

 $aList = array("a", "e", "d", "b", "c"); sort($aList); $iDesiredNumberOfColumns = 3; $iListLength = count($aList); $aListInColumns = array(); $iRowNumber = 0; for($iIndex = 0; $iIndex < $iListLength; $iIndex++) { $iColumnNumber = $iIndex % 3; if($iIndex != 0 && $iColumnNumber == 0) { $iRowNumber++; } $aListInColumns[$iRowNumber][$iColumnNumber] = $aList[$iIndex]; } 

Просто запустил его на моем локальном сервере (и исправил опечатку), и он выводит как:

 Array ( [0] => Array ( [0] => a [1] => b [2] => c ) [1] => Array ( [0] => d [1] => e ) ) 

Вероятно, есть более аккуратный способ сделать это (это немного процедурный), но он должен выполнять эту работу.

Как насчет:

 $arrs = array( array('a','b','c'), array('a','b','c','d'), array('a','b','c','d','e'), array('a','b','c','d','e','f'), array('a','b','c','d','e','f','g') ); $nbcols = 3; foreach ($arrs as $arr) { $arr_size = count($arr); $nblines = ceil($arr_size/$nbcols); $res = array(); $l = 0; foreach ($arr as $el) { if ($l == $arr_size - 1 && count($res[0]) < $nbcols) $l=0; $res[$l%$nblines][] = $el; $l++; } print_r($res); } 

вывод:

 Array ( [0] => Array ( [0] => a [1] => b [2] => c ) ) Array ( [0] => Array ( [0] => a [1] => c [2] => d ) [1] => Array ( [0] => b ) ) Array ( [0] => Array ( [0] => a [1] => c [2] => e ) [1] => Array ( [0] => b [1] => d ) ) Array ( [0] => Array ( [0] => a [1] => c [2] => e ) [1] => Array ( [0] => b [1] => d [2] => f ) ) Array ( [0] => Array ( [0] => a [1] => d [2] => g ) [1] => Array ( [0] => b [1] => e ) [2] => Array ( [0] => c [1] => f ) ) 

Для этого вам необходимо выполнить две операции:

Сначала разделите массив на 3 группы, как можно более равномерно.

 function array_grouped($arr, $group_count) { if (!count($arr)) return array(); $result = array(); for ($i = $group_count; $i > 0; --$i) { # break off the next ceil(remaining count / remaining columns) elements # (avoiding FP math, cause that way lies madness) $result[] = array_splice($arr, 0, ((count($arr)-1) / $i) + 1); } return $result; } 

Затем, «транспонируйте» массив, чтобы строки и столбцы переключались местами.

 function array_transposed($arr) { $result = array(); foreach ($arr as $x => $subarr) { foreach ($subarr as $y => $val) { if (!isset($result[$y])) $result[$y] = array(); $result[$y][$x] = $val; } } return $result; } 

array_transposed(array_grouped($arr, 3)) дает вам записи в том порядке, в котором вы хотите.

YAYAYAY !! Я понял. Вы можете превратить это в функцию, если будете делать это регулярно.

 # Here we setup our array and the number of columns we want. $myArray = range('a','d'); $numCols = 3; # Here we break ourselves up into columns for ($i = 0; $i < $numCols; $i++) { $numRows = ceil(count($myArray) / ($numCols - $i)); $columns[$i] = array_slice($myArray,0,$numRows); $myArray = array_slice($myArray,$numRows); } # Here we transpose our array to be in rows instead of columns. for ($i = 0; $i < $numCols; $i++) { for ($j = 0; $j < count($columns[$i]); $j++) { $rows[$j][$i] = $columns[$i][$j]; } } # Our rows are now in $rows var_dump($rows); 

Результатом этого является:

 array(2) { [0]=> array(3) { [0]=> string(1) "a" [1]=> string(1) "c" [2]=> string(1) "d" } [1]=> array(1) { [0]=> string(1) "b" } } 

Если сказать коротко, то вот метод для этого алгоритма.

 /** * @param array $toTransform * @param int $columnsMax * @return array */ private function transformation( array $toTransform, $columnsMax = 3 ) { // First divide array as you need $listlen = count( $toTransform ); $partlen = floor( $listlen / $columnsMax ); $partrem = $listlen % $columnsMax; $partition = array(); $mark = 0; for ( $px = 0; $px < $columnsMax; $px++ ) { $incr = ( $px < $partrem ) ? $partlen + 1 : $partlen; $partition[ $px ] = array_slice( $toTransform, $mark, $incr ); $mark += $incr; } // Secondly fill empty slots for easy template use $result = array(); for ( $i = 0; $i < count( $partition[0] ); $i++ ) { $tmp = array(); foreach ( $partition as $column ) { if ( isset( $column[ $i ] ) ) { $tmp[] = $column[ $i ]; } else { $tmp[] = ''; } } $result[] = $tmp; } return $result; } 

Кроме того, я включил тест PHPUnit. Вы можете найти его на этой ссылке .