Люблю то, что делаю!
С нами с 22.10.06
Сообщения: 5053
Рейтинг: 4418
|
Добавлено: 12/01/12 в 13:17 |
Столкнулся с проблемкой, есть файл (data.txt) со строками:
text|1|info|date
text|7|info|date
text|3|info|date
text|5|info|date
text|4|info|date
text|6|info|date
text|2|info|date
Мне нужно все строки отсортировать в порядке убывания по второму значению, т.е. по цифрам, и потом стими данными работать.
Записывать это никуда ненужно.
Вот впринципе сам код:
Код: [развернуть] | $file = file("data.txt");
$loc = "";
$count = count($file);
for( $i = 1; $i < $count; $i += 1 )
{
$res = explode( "|", $file[ $i ] );
$loc .= $res[3].'|';
}
$str = explode("|", $loc);
$k = 0;
echo $str[ $k++ ].'<br>'; |
|
|
|
|
Добрых Дел Мастер
С нами с 03.05.08
Сообщения: 3143
Рейтинг: 1227
|
Добавлено: 12/01/12 в 14:47 |
<?php
$lines = file('1.txt', FILE_USE_INCLUDE_PATH | FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
print_r($lines);
foreach ($lines as $k => $line) {
$chunks = explode('|', $line);
$result[$k] = $chunks[1];
}
arsort($result);
print_r($result);
foreach ($result as $k => $line) {
echo $lines[$k] . "\n";
}
вывод:
u@u:~/share$ php index.php
Array
(
[0] => text|1|info|date
[1] => text|7|info|date
[2] => text|3|info|date
[3] => text|5|info|date
[4] => text|4|info|date
[5] => text|6|info|date
[6] => text|2|info|date
)
Array
(
[1] => 7
[5] => 6
[3] => 5
[4] => 4
[2] => 3
[6] => 2
[0] => 1
)
text|7|info|date
text|6|info|date
text|5|info|date
text|4|info|date
text|3|info|date
text|2|info|date
text|1|info|date
u@u:~/share$
|
|
пришел к победе коммунистического труда
|
6
|
|
|
С нами с 05.05.05
Сообщения: 1913
Рейтинг: 1134
|
Добавлено: 12/01/12 в 14:58 |
Код: | $file = file('data.txt'); // некий массив с элементами содержащими строки в нашем формате
function mySort($a, $b) {
$r1 = explode('|', $a);
$r2 = explode('|', $b);
return strcmp($r1[1], $r2[1]);
}
usort($file, 'mySort');
echo '<pre>';
var_dump($file); |
|
|
|
|
programmer
С нами с 08.12.02
Сообщения: 7613
Рейтинг: 5760
|
Добавлено: 12/01/12 в 15:15 |
определенно последний вариант +1
|
|
|
|
Люблю то, что делаю!
С нами с 22.10.06
Сообщения: 5053
Рейтинг: 4418
|
Добавлено: 12/01/12 в 15:32 |
если допусим формат поменять до такого состояния и сортировать по четвертому параметру:
name|7854|490|0.00623|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
name|6542|310|0.00103|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
name|7542|100|0.00825|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
то как быть, просто хчу разобраться в работе скрипта, за него спасибо отдельное, он то что нужно.
Сейчас у меня рабочий скрипт выглядет так:
Код: [развернуть] |
<?php
$loc = "";
$file = file('data.txt');
function mySort($a, $b) {
$r1 = explode('|', $a);
$r2 = explode('|', $b);
return strcmp($r1[1], $r2[1]);
}
usort($file, 'mySort');
$count = count($file);
for( $i = 1; $i < $count; $i += 1 )
{
$res = explode( "|", $file[ $i ] );
$loc .= $res[1].'|';
}
$str = explode("|", $loc);
$n = 0;
echo $str[ $n++ ].'<br>';
echo $str[ $n++ ].'<br>';
echo $str[ $n++ ].'<br>';
?>
|
echo $str[ $n++ ].'<br>'; - это для того чтобы можно было на странице в разных местах вставку делать по типу <?php echo $str[ $n++ ]; ?>
Но как быть если нудно сортировать по четвертому параметру немогу понять.
И интересно как такой скрипт будет нагружать сервер если файл с данными будет около 1 mb
|
|
|
|
С нами с 05.05.05
Сообщения: 1913
Рейтинг: 1134
|
Добавлено: 12/01/12 в 15:50 |
у нас формат какой? строка поделена через вертикальную черту |
мы использовали функцию обратного вызова mySort
в которой находим строки с функцией explode, которая в свою очередь превращает нашу строку $a и $b в массивы соответственно $r1 и $r2, где нумерация элементов идет с 0
в первом случае мы сортировали по второму параметру, т.е. сравнивали $r1[1] и $r2[1]
соответственно, на нужно только выбрать тот параметр по которому как нам кажется целесообразней сравнивать строки:
если по четвёртому $r1[3] и $r2[3] и т.д.
пс: чтобы отсортировать элементы в обратном порядке перед strcmp надо поставить минус.
|
|
|
|
Люблю то, что делаю!
С нами с 22.10.06
Сообщения: 5053
Рейтинг: 4418
|
Добавлено: 12/01/12 в 15:53 |
затупил, у нас же с нуля счет, а я чет думаю как оно, и теперь стало понятно что да как.
|
|
|
|
С нами с 09.03.09
Сообщения: 6053
Рейтинг: 3538
|
Добавлено: 12/01/12 в 15:57 |
Lexikon писал: | если допусим формат поменять до такого состояния и сортировать по четвертому параметру: |
Код: | $data = array(
'name|7854|490|0.000623|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|',
'name|6542|310|0.00103|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|',
'name|7542|100|0.00825|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|'
);
$result = yacc_sort( $data, 4 );
echo('<pre>'.print_r($result,1).'</pre>'); |
Код: [развернуть] | function yacc_sort( $data, $number ) {
$x = array();
foreach( $data as $s )
$x[] = explode( '|', $s );
_yacc_sort( $x, $number - 1 );
foreach( $x as $k => $v )
$x[ $k ] = implode( $v, '|' );
return $x;
}
function _yacc_sort ( &$array, $number ) {
$x = array();
$y = array();
reset( $array );
foreach( $array as $i => $v )
$x[ $i ] = $v[ $number ];
arsort( $x, SORT_NUMERIC );
foreach( $x as $i => $v )
$y[ $i ] = $array[ $i ];
$array = $y;
} |
Работает в ~10 раз быстрее, чем первый вариант. Соответствено памяти на большом массиве $data может отожрать.
|
|
|
|
С нами с 05.05.05
Сообщения: 1913
Рейтинг: 1134
|
Добавлено: 12/01/12 в 16:05 |
Yacc писал: | Работает в ~10 раз быстрее, чем первый вариант. Соответствено памяти на большом массиве $data может отожрать. |
а второго?
|
|
|
|
С нами с 09.03.09
Сообщения: 6053
Рейтинг: 3538
|
Добавлено: 12/01/12 в 16:23 |
freeek писал: | а второго? icon_rolleyes.gif |
Я имел ввиду твой вариант.
|
|
|
|
Люблю то, что делаю!
С нами с 22.10.06
Сообщения: 5053
Рейтинг: 4418
|
Добавлено: 12/01/12 в 16:48 |
всё отлично, но в файле с данными оказалось еще загвоздка, все данные идут так
flag
name|700|490|0.007|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
name|500|310|0.005|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
name|100|100|0.001|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
name|300|490|0.003|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
name|800|310|0.008|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
name|400|100|0.004|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
name|900|490|0.009|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
name|200|310|0.002|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
name|600|100|0.006|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
т.е. всё начинается со второй строки
сделал так:
Код: [развернуть] |
<?php
$data = '';
$loc = '';
$file = file('data.txt');
$count = count($file);
for( $i = 1; $i < $count; $i += 1 )
{
$data .= $file[$i].'\n';
}
//echo $data;
$data_n = explode( "\n", $data );
function mySort($a, $b)
{
$r1 = explode('|', $a);
$r2 = explode('|', $b);
return strcmp($r1[3], $r2[3]);
}
usort($data_n, 'mySort');
$count = count($data_n);
//echo $count;
for( $i = 0; $i < $count; $i += 1 )
{
$res = explode( "|", $data_n[ $i ] );
$loc .= $res[1].'|';
}
$str = explode("|", $loc);
$n = 0;
echo $str[ $n++ ].'<br>';
echo $str[ $n++ ].'<br>';
echo $str[ $n++ ].'<br>';
echo $str[ $n++ ].'<br>';
echo $str[ $n++ ].'<br>';
echo $str[ $n++ ].'<br>';
echo $str[ $n++ ].'<br>';
echo $str[ $n++ ].'<br>';
echo $str[ $n++ ].'<br>';
?>
|
|
|
|
|
Добрых Дел Мастер
С нами с 03.05.08
Сообщения: 3143
Рейтинг: 1227
|
Добавлено: 12/01/12 в 16:54 |
мне одному кажется что вы херней занимаетесь?
1. зачем на пхп писать то что уже реализовано и запаковано в одну php-команду?
2. зачем юзать функцию обратного вызова и писать свою обработку массива? тут обработка простейшая. все написано до вас. в пхп овер 20 функций сортировки...
и вот она одна пхп-команда реализующая сортировку, без хуйни
<?php
$lines = file('1.txt', FILE_USE_INCLUDE_PATH | FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); // прочитали в массив
foreach ($lines as $k => $line) {
$chunks = explode('|', $line); // парсим строку
$result[$k] = $chunks[1]; // забираем в отдельный массив циферки (или буковки тут могут быть. похуй)
}
arsort($result); // сортируем их!
foreach ($result as $k => $line) {
$result2[] = $lines[$k]; // формируем массив
}
print_r($result2); // профит
u@u:~/share$ php index.php
Array
(
[0] => text|7|info|date
[1] => text|6|info|date
[2] => text|5|info|date
[3] => text|4|info|date
[4] => text|3|info|date
[5] => text|2|info|date
[6] => text|1|info|date
)
калбек-функции нужны для:
1. нетривиальной хитровыебанной сортировки.
2. для упаковки этой громоздской хуйни в функцию и вынос в файл с глаз долой.
1. тут сортировка нативная совершенно.
2. совать 3 строки в калбек НЕ принято. в форич такое суют сразу
|
|
пришел к победе коммунистического труда
|
6
|
|
|
Добрых Дел Мастер
С нами с 03.05.08
Сообщения: 3143
Рейтинг: 1227
|
Добавлено: 12/01/12 в 16:58 |
Lexikon писал: | всё отлично, но в файле с данными оказалось еще загвоздка, все данные идут так
т.е. всё начинается со второй строки
|
array_shift — Извлечь первый элемент массива, сокращая массив на 1.
ТС тебе совет. найти время прогнать ВЕСЬ ман. просто выписать все функции языка абсолютно, и перевести на русский.
|
|
пришел к победе коммунистического труда
|
6
|
|
|
С нами с 09.03.09
Сообщения: 6053
Рейтинг: 3538
|
Добавлено: 12/01/12 в 17:15 |
FXIX писал: | array_shift — Извлечь первый элемент массива, сокращая массив на 1. |
array_shift операция сложности O(n), так как требуется перестройка индекса.
Lexikon писал: | т.е. всё начинается со второй строки |
unset( $data[ 0 ] );
|
|
|
|
С нами с 05.05.05
Сообщения: 1913
Рейтинг: 1134
|
Добавлено: 12/01/12 в 17:23 |
Lexikon писал: | всё отлично, но в файле с данными оказалось еще загвоздка, все данные идут так
flag
name|700|490|0.007|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
name|500|310|0.005|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
name|100|100|0.001|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
name|300|490|0.003|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
name|800|310|0.008|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
name|400|100|0.004|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
name|900|490|0.009|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
name|200|310|0.002|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
name|600|100|0.006|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
т.е. всё начинается со второй строки
|
что то мне кажется, здесь много лишнего наворочено, если начинается со второй строки, вырежи первый элемент
Код: | $file = array_slice(file('sort'), 1);
function newSort($array, $byElem = 1, $asc = true) {
$temp = array();
--$byElem;
foreach ($array as &$string) {
$a = explode('|', $string);
$temp[$string] = $a[$byElem];
}
!!$asc ? asort($temp) : arsort($temp);
return array_keys($temp);
}
$result = newSort($file, 2, false);
echo '<pre>';
print_r($result); |
на от случай если не устраивает сортировка с обратным вызовом
ps: или удалить через unset
|
|
|
|
С нами с 09.03.09
Сообщения: 6053
Рейтинг: 3538
|
Добавлено: 12/01/12 в 17:43 |
Код: | function fxix_sort( $data, $number ) {
$r = array();
foreach( $data as $k => $v ) {
$c = explode( '|', $v );
$r[ $k ] = $c[ $number ];
}
arsort( $r, SORT_NUMERIC );
$s = array();
foreach( $r as $k => $v )
$s[] = $data[ $k ];
return $s;
} |
Работает в два раза быстрее, чем мой вариант.
|
|
|
|
С нами с 05.05.05
Сообщения: 1913
Рейтинг: 1134
|
Добавлено: 12/01/12 в 17:47 |
как проверяешь? через профайлер?
ну а мой последний?
|
|
|
|
Люблю то, что делаю!
С нами с 22.10.06
Сообщения: 5053
Рейтинг: 4418
|
Добавлено: 12/01/12 в 17:54 |
freeek писал: | что то мне кажется, здесь много лишнего наворочено, если начинается со второй строки, вырежи первый элемент |
Вижу весь массив, пробую вывести что то отдельно,
echo $result [1];
и ошибка Notice: Undefined offset ...
такая же херня была и в моем варианте, то выдавало Notice: Undefined offset ... но правда с результатом.
х.з. немогу понять.
|
|
|
|
С нами с 09.03.09
Сообщения: 6053
Рейтинг: 3538
|
Добавлено: 12/01/12 в 17:59 |
freeek писал: | ну а мой последний? |
Примерно та же, но он будет работать не правильно, если среди сортируемых данных найдутся одинаковые.
Последний раз редактировалось: Yacc (12/01/12 в 17:59), всего редактировалось 1 раз
|
|
|
|
С нами с 05.05.05
Сообщения: 1913
Рейтинг: 1134
|
Добавлено: 12/01/12 в 17:59 |
Lexikon писал: | Вижу весь массив, пробую вывести что то отдельно,
echo $result [1];
и ошибка Notice: Undefined offset ...
такая же херня была и в моем варианте, то выдавало Notice: Undefined offset ... но правда с результатом.
х.з. немогу понять. |
а можно весь код, как ты используешь, если весь массив видишь, и с индексами там все в порядке, то ошибки нет, Notice: Undefined offset такая ерунда вылазит, когда типа нет проверки на существование того или иного индекса в массиве
|
|
|
|
С нами с 05.05.05
Сообщения: 1913
Рейтинг: 1134
|
Добавлено: 12/01/12 в 18:00 |
Yacc писал: | Примерно та же, но он будет работать не правильно, если среди сортируемых данных найдутся одинаковые. |
это почему?))
он делает все тоже самое что и твоя функция, просто ты извелаешь ключи через цикл, а я через функцию
пс: имеешь ввиду одинаковые строки?
Последний раз редактировалось: freeek (12/01/12 в 18:02), всего редактировалось 1 раз
|
|
|
|
Добрых Дел Мастер
С нами с 03.05.08
Сообщения: 3143
Рейтинг: 1227
|
Добавлено: 12/01/12 в 18:00 |
Yacc писал: | Примерно та же, но он будет работать не правильно, если среди сортируемых данных найдутся одинаковые. |
да. при одинаковых циферках
|
|
пришел к победе коммунистического труда
|
6
|
|
|
С нами с 05.05.05
Сообщения: 1913
Рейтинг: 1134
|
Добавлено: 12/01/12 в 18:07 |
по 3 параметру с одинаковыми циферками. (freebsd 7, php 5.2.14)
Код: | $file = array_slice(file('sort'), 1); //поставите свое
function newSort($array, $byElem = 1, $asc = true) {
$temp = array();
--$byElem;
foreach ($array as &$string) {
$a = explode('|', $string);
$temp[$string] = $a[$byElem];
}
!!$asc ? asort($temp) : arsort($temp);
return array_keys($temp);
}
$file = newSort($file, 3);
echo '<pre>';
print_r($file); |
Код: | Array
(
[0] => name|100|100|0.001|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
[1] => name|600|100|0.006|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
[2] => name|400|100|0.004|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
[3] => name|200|310|0.002|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
[4] => name|800|310|0.008|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
[5] => name|500|310|0.005|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
[6] => name|300|490|0.003|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
[7] => name|900|490|0.009|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
[8] => name|700|490|0.007|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
) |
|
|
|
|
С нами с 09.03.09
Сообщения: 6053
Рейтинг: 3538
|
Добавлено: 12/01/12 в 18:08 |
freeek писал: | это почему? |
Потому что массив в пхп - это хэш-таблица, а индексы последней, как известно должны быть уникальны.
|
|
|
|
Добрых Дел Мастер
С нами с 03.05.08
Сообщения: 3143
Рейтинг: 1227
|
Добавлено: 12/01/12 в 18:09 |
Yacc писал: | array_shift операция сложности O(n), так как требуется перестройка индекса.
unset( $data[ 0 ] ); |
ты бдишь не там где надо . к тому же индексы теперь будут не с 0 а с 1 начинаться. массив начинающийся не с нуля - или неправильный (кто это в голове будет держать? чтобы дальше по коду не наебаться. и не ловить ощибки 2 дня) или ассоциативный. он ни то ни другое
вообще в кусок кода отвечающий за сортировку - не надо подмешивать логику работы с 10гиговыми файлами. если ты на это намекаешь говоря про память. случай когда файл не лезет в оперативку. Ну так это логика должна быть в коде который реализует обработку файла по частям
|
|
пришел к победе коммунистического труда
|
6
|
|
|