Реклама на сайте Advertise with us

Сортировка строковых данных

Расширенный поиск по форуму
 
Новая тема Новая тема   
Автор
Поиск в теме:

Люблю то, что делаю!

С нами с 22.10.06
Сообщения: 5053
Рейтинг: 4418


Передовик Master-X (16.12.2014) Передовик Master-X (16.02.2017) Передовик Master-X (01.03.2017) Передовик Master-X (16.03.2017) Передовик Master-X (01.09.2017) Ветеран трепа Master-X (16.09.2017)
Ссылка на сообщениеДобавлено: 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
Мне нужно все строки отсортировать в порядке убывания по второму значению, т.е. по цифрам, и потом стими данными работать.
Записывать это никуда ненужно.
Вот впринципе сам код:
Код: [развернуть]

Push Траф для Арбитража : Раз | Два
Есть СНГ траф? Лей сюда!

0
 

Добрых Дел Мастер

С нами с 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);

7
 

programmer

С нами с 08.12.02
Сообщения: 7607
Рейтинг: 5752

Ссылка на сообщениеДобавлено: 12/01/12 в 15:15       Ответить с цитатойцитата 

определенно последний вариант +1

крипта на ByBit

6
 

Люблю то, что делаю!

С нами с 22.10.06
Сообщения: 5053
Рейтинг: 4418


Передовик Master-X (16.12.2014) Передовик Master-X (16.02.2017) Передовик Master-X (01.03.2017) Передовик Master-X (16.03.2017) Передовик Master-X (01.09.2017) Ветеран трепа Master-X (16.09.2017)
Ссылка на сообщениеДобавлено: 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|
то как быть, просто хчу разобраться в работе скрипта, за него спасибо отдельное, он то что нужно.

Сейчас у меня рабочий скрипт выглядет так:

Код: [развернуть]


echo $str[ $n++ ].'<br>'; - это для того чтобы можно было на странице в разных местах вставку делать по типу <?php echo $str[ $n++ ]; ?>
Но как быть если нудно сортировать по четвертому параметру немогу понять.
И интересно как такой скрипт будет нагружать сервер если файл с данными будет около 1 mb

Push Траф для Арбитража : Раз | Два
Есть СНГ траф? Лей сюда!

0
 



С нами с 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 надо поставить минус.

6
 

Люблю то, что делаю!

С нами с 22.10.06
Сообщения: 5053
Рейтинг: 4418


Передовик Master-X (16.12.2014) Передовик Master-X (16.02.2017) Передовик Master-X (01.03.2017) Передовик Master-X (16.03.2017) Передовик Master-X (01.09.2017) Ветеран трепа Master-X (16.09.2017)
Ссылка на сообщениеДобавлено: 12/01/12 в 15:53       Ответить с цитатойцитата 

затупил, у нас же с нуля счет, а я чет думаю как оно, и теперь стало понятно что да как. smail54.gif

Push Траф для Арбитража : Раз | Два
Есть СНГ траф? Лей сюда!

0
 



С нами с 09.03.09
Сообщения: 6053
Рейтинг: 3538


Передовик Master-X (01.11.2009) Передовик Master-X (16.11.2009) Передовик Master-X (01.02.2011) Передовик Master-X (01.12.2011) Передовик Master-X (16.12.2011) Ветеран трепа Master-X (01.01.2014)
Ссылка на сообщениеДобавлено: 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>');


Код: [развернуть]


Работает в ~10 раз быстрее, чем первый вариант. Соответствено памяти на большом массиве $data может отожрать. icon_smile.gif

6
 



С нами с 05.05.05
Сообщения: 1913
Рейтинг: 1134

Ссылка на сообщениеДобавлено: 12/01/12 в 16:05       Ответить с цитатойцитата 

Yacc писал:
Работает в ~10 раз быстрее, чем первый вариант. Соответствено памяти на большом массиве $data может отожрать. icon_smile.gif


а второго? icon_rolleyes.gif

6
 



С нами с 09.03.09
Сообщения: 6053
Рейтинг: 3538


Передовик Master-X (01.11.2009) Передовик Master-X (16.11.2009) Передовик Master-X (01.02.2011) Передовик Master-X (01.12.2011) Передовик Master-X (16.12.2011) Ветеран трепа Master-X (01.01.2014)
Ссылка на сообщениеДобавлено: 12/01/12 в 16:23       Ответить с цитатойцитата 

freeek писал:
а второго? icon_rolleyes.gif

Я имел ввиду твой вариант. icon_smile.gif

6
 

Люблю то, что делаю!

С нами с 22.10.06
Сообщения: 5053
Рейтинг: 4418


Передовик Master-X (16.12.2014) Передовик Master-X (16.02.2017) Передовик Master-X (01.03.2017) Передовик Master-X (16.03.2017) Передовик Master-X (01.09.2017) Ветеран трепа Master-X (16.09.2017)
Ссылка на сообщениеДобавлено: 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|
т.е. всё начинается со второй строки

сделал так:

Код: [развернуть]

Push Траф для Арбитража : Раз | Два
Есть СНГ траф? Лей сюда!

0
 

Добрых Дел Мастер

С нами с 03.05.08
Сообщения: 3143
Рейтинг: 1227

Ссылка на сообщениеДобавлено: 12/01/12 в 16:54       Ответить с цитатойцитата 

мне одному кажется что вы херней занимаетесь? trollface.png

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


Передовик Master-X (01.11.2009) Передовик Master-X (16.11.2009) Передовик Master-X (01.02.2011) Передовик Master-X (01.12.2011) Передовик Master-X (16.12.2011) Ветеран трепа Master-X (01.01.2014)
Ссылка на сообщениеДобавлено: 12/01/12 в 17:15       Ответить с цитатойцитата 

FXIX писал:
array_shift — Извлечь первый элемент массива, сокращая массив на 1.

array_shift операция сложности O(n), так как требуется перестройка индекса. icon_smile.gif


Lexikon писал:
т.е. всё начинается со второй строки

unset( $data[ 0 ] );

6
 



С нами с 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

6
 



С нами с 09.03.09
Сообщения: 6053
Рейтинг: 3538


Передовик Master-X (01.11.2009) Передовик Master-X (16.11.2009) Передовик Master-X (01.02.2011) Передовик Master-X (01.12.2011) Передовик Master-X (16.12.2011) Ветеран трепа Master-X (01.01.2014)
Ссылка на сообщениеДобавлено: 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;
}


Работает в два раза быстрее, чем мой вариант.

6
 



С нами с 05.05.05
Сообщения: 1913
Рейтинг: 1134

Ссылка на сообщениеДобавлено: 12/01/12 в 17:47       Ответить с цитатойцитата 

как проверяешь? через профайлер?
ну а мой последний?

6
 

Люблю то, что делаю!

С нами с 22.10.06
Сообщения: 5053
Рейтинг: 4418


Передовик Master-X (16.12.2014) Передовик Master-X (16.02.2017) Передовик Master-X (01.03.2017) Передовик Master-X (16.03.2017) Передовик Master-X (01.09.2017) Ветеран трепа Master-X (16.09.2017)
Ссылка на сообщениеДобавлено: 12/01/12 в 17:54       Ответить с цитатойцитата 

freeek писал:
что то мне кажется, здесь много лишнего наворочено, если начинается со второй строки, вырежи первый элемент


Вижу весь массив, пробую вывести что то отдельно,

echo $result [1];

и ошибка Notice: Undefined offset ...
такая же херня была и в моем варианте, то выдавало Notice: Undefined offset ... но правда с результатом.
х.з. немогу понять.

Push Траф для Арбитража : Раз | Два
Есть СНГ траф? Лей сюда!

0
 



С нами с 09.03.09
Сообщения: 6053
Рейтинг: 3538


Передовик Master-X (01.11.2009) Передовик Master-X (16.11.2009) Передовик Master-X (01.02.2011) Передовик Master-X (01.12.2011) Передовик Master-X (16.12.2011) Ветеран трепа Master-X (01.01.2014)
Ссылка на сообщениеДобавлено: 12/01/12 в 17:59       Ответить с цитатойцитата 

freeek писал:
ну а мой последний?

Примерно та же, но он будет работать не правильно, если среди сортируемых данных найдутся одинаковые. icon_smile.gif

Последний раз редактировалось: Yacc (12/01/12 в 17:59), всего редактировалось 1 раз

6
 



С нами с 05.05.05
Сообщения: 1913
Рейтинг: 1134

Ссылка на сообщениеДобавлено: 12/01/12 в 17:59       Ответить с цитатойцитата 

Lexikon писал:
Вижу весь массив, пробую вывести что то отдельно,

echo $result [1];

и ошибка Notice: Undefined offset ...
такая же херня была и в моем варианте, то выдавало Notice: Undefined offset ... но правда с результатом.
х.з. немогу понять.


а можно весь код, как ты используешь, если весь массив видишь, и с индексами там все в порядке, то ошибки нет, Notice: Undefined offset такая ерунда вылазит, когда типа нет проверки на существование того или иного индекса в массиве

6
 



С нами с 05.05.05
Сообщения: 1913
Рейтинг: 1134

Ссылка на сообщениеДобавлено: 12/01/12 в 18:00       Ответить с цитатойцитата 

Yacc писал:
Примерно та же, но он будет работать не правильно, если среди сортируемых данных найдутся одинаковые. icon_smile.gif


это почему?))
он делает все тоже самое что и твоя функция, просто ты извелаешь ключи через цикл, а я через функцию


пс: имеешь ввиду одинаковые строки?

Последний раз редактировалось: freeek (12/01/12 в 18:02), всего редактировалось 1 раз

6
 

Добрых Дел Мастер

С нами с 03.05.08
Сообщения: 3143
Рейтинг: 1227

Ссылка на сообщениеДобавлено: 12/01/12 в 18:00       Ответить с цитатойцитата 

Yacc писал:
Примерно та же, но он будет работать не правильно, если среди сортируемых данных найдутся одинаковые. icon_smile.gif

да. при одинаковых циферках

пришел к победе коммунистического труда

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|

)

6
 



С нами с 09.03.09
Сообщения: 6053
Рейтинг: 3538


Передовик Master-X (01.11.2009) Передовик Master-X (16.11.2009) Передовик Master-X (01.02.2011) Передовик Master-X (01.12.2011) Передовик Master-X (16.12.2011) Ветеран трепа Master-X (01.01.2014)
Ссылка на сообщениеДобавлено: 12/01/12 в 18:08       Ответить с цитатойцитата 

freeek писал:
это почему?

Потому что массив в пхп - это хэш-таблица, а индексы последней, как известно должны быть уникальны. icon_smile.gif

6
 

Добрых Дел Мастер

С нами с 03.05.08
Сообщения: 3143
Рейтинг: 1227

Ссылка на сообщениеДобавлено: 12/01/12 в 18:09       Ответить с цитатойцитата 

Yacc писал:
array_shift операция сложности O(n), так как требуется перестройка индекса. icon_smile.gif

unset( $data[ 0 ] );


ты бдишь не там где надо smail101.gif. к тому же индексы теперь будут не с 0 а с 1 начинаться. массив начинающийся не с нуля - или неправильный (кто это в голове будет держать? чтобы дальше по коду не наебаться. и не ловить ощибки 2 дня) или ассоциативный. он ни то ни другое


вообще в кусок кода отвечающий за сортировку - не надо подмешивать логику работы с 10гиговыми файлами. если ты на это намекаешь говоря про память. случай когда файл не лезет в оперативку. Ну так это логика должна быть в коде который реализует обработку файла по частям

trollface.png

пришел к победе коммунистического труда

6
 
Новая тема Новая тема   

Текстовая реклама в форме ответа
Заголовок и до четырех строчек текста
Длина текста до 350 символов
Купить рекламу в этом месте!


Перейти:  



Спонсор раздела Стань спонсором этого раздела!

Реклама на сайте Advertise with us

Опросы

Рецепт новогоднего блюда 2022



Обсудите на форуме обсудить (11)
все опросы »