Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Помогите с очень сложной сортировкой

76K
16 ноября 2011 года
reddd
2 / / 16.11.2011
Помогите решить проблемму:

есть таблица route поля: ostanovki и weight - тип полей текстовые
есть таблица stop поля: title и id_ostanovki

При добавлении маршрута пользователь используя чекбокс выбирает нужные ему остановки транспорта и выставляет вес(последовательность) для каждой остановки, чтобы сделать по порядку следования остановки.

Выбрав нужные и указав вес, через функцию implode, я забиваю в поля ostanovki и weight массив значений разделенных запятой , например в поле ostanovki такое- 1,2,3,4,5,8,9,10
а в поле weight такое 1,4,3,7,5,6,2,8 то есть по маршруту первая остановка это 1 затем 9 затем 3 итд.

Подскажите как теперь вывести по порядку согласно весу названия остановок?

Каждый номер в массиве в поле ostanovki таблицы route соответствует полю id_ostanovki в другой таблице stop

ОЧЕНЬ прошу помочь!
244
16 ноября 2011 года
UAS
2.0K / / 19.07.2006
МОИ ГЛАЗА!! Сортировка не сложная, просто сделана через жопу.

Почитайте про нормализацию баз данных.
1) Эти поля текстовыми быть НЕ должны
2) Каждое значение - отдельная строка. Все хранить через запятую - неверно.
Делайте таблицу с названиями и ID остановок. Делайте таблицу маршрутов, где указываете идентификатор маршрута. Делаете сводную таблицу из полей "id маршрута", "id остановки", "вес остановки".
Все, далее отсортировать ума особо много не надо.
49K
17 ноября 2011 года
vorobej
129 / / 17.11.2011
Ну да с нормализацией тут полный кирдык, но думаю он имел ввиду что-то вроде эдакого решения:

Тут тебе надо про рекурсивные ф-ции почитать.

Код:
$ostanovki = explode(',', '1,2,3,4,5,8,9,10');
$ves = explode(',', '1,4,3,7,5,6,2,8');

function findMin($a, $z, $new=array()) {

        $kicker = 99999;

        $min = min($a); if($min == $kicker) return $new;
       
        foreach($a as $i=>$j) {
            if($j == $min)  {
                $a[$i] = $kicker;
                array_push($new, ( isset($z[$i]) ? $z[$i] : '?' ) );
            }
        }
        return findMin($a,$z,$new);
    }


$sorted = findMin($ves,$ostanovki);
print_r($sorted);


Edit:

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

$a - входящий вес.
$z - остановки
$new = Результат

Каждый раз когда ф-ция срабатывает она:

1. Находит минимальное число из массива А
2. Заменяет его на очень большое число (киккер = 99999)
3. В новый массив заносит ИД остановки по индексу найденного числа
4. Вызывает саму себя (рекурсия), но новый входящий массив остановок уже изменен (найденной число стало 99999 и уже больше не повторится, ищим следующее минимальное число)
5. Если минимальное число 99999, значит мы нашли все числа. Возвращаем результат (который с каждой работы ф-ции прибавляется на одно число, тобишь следующей иди остановки )

PPS Как я сегодня расписался.. ;)




Наслаждайся =)

Грубо говоря ты получишь в ответ массив с отсортированными индексами остановки. НО! Массивы должны быть одной длинны. Апгрейди уже по своему усмотрению

P.S: Обещал? Помог! =))) : http://www.feedbackme.org/c1d53b7a97707b5cd1815c8d228d8ef1x23
244
17 ноября 2011 года
UAS
2.0K / / 19.07.2006
vorobej, зачем такое объемное извращение? Бред, а не функция. В таком случае надо сделать массив, где ключи - это вес, а значение - это ID остановки. Затем отсортировать по ksort. Всё что выше - образец как делать не надо.

Цитата:
но думаю он имел ввиду что-то вроде эдакого решения

Нет, не имел. Ему же ещё надо название остановки вывести. Такие задачи должны решаться одним запросом. Пока что решений два: перепроектировать БД, либо писать хранимую процедуру.

10
17 ноября 2011 года
Freeman
3.2K / / 06.03.2004
Цитата: UAS
перепроектировать БД


А начать надо с нормальных идентификаторов.

49K
17 ноября 2011 года
vorobej
129 / / 17.11.2011
Ну вы даете... Человек просил ПОМОЧЬ отсортировать массивы, а не сказать ему, что он/она не компетентны в проектировании ДБ. И моя "бредовая" ф-ция это делает.

Цитата:
В таком случае надо сделать массив, где ключи - это вес, а значение - это ID остановки.



И че дальше? Я привык такие задачи на С решать. Может на ПХП и есть вариант попроще. Решай, коли такой умный:

$ostanovki = explode(',', '1435,2232,2343,5674,235,58,769,231,1120');
$ves = explode(',', '10,43,33,72,51,62,23,23,18');

ПС: Заметь, вес одной остановки повторяется (они просто идут подряд)

Цитата:


$ostanovki = explode(',', '1,2,3,4,5,8,9,10');
$ves = explode(',', '1,4,3,7,5,6,2,8');

$b_ = array();
foreach($ves as $i=>$j) {
$b_[$j] = $ostanovki[$i];
}

ksort($b_);



Вес не должен повторяться. Хоть и признаюсь, малька ночью перемудрил (я не знал о существовании ксорт, спасибо, все-таки кое чему научил).

49K
17 ноября 2011 года
vorobej
129 / / 17.11.2011
А что касаемо базы:

Таблица A: route -> Id, ,., (там дата, название, че угодно.. главное Ид)
Таблица B: stop -> ost_id (INT), title
Таблица C: route_r -> ost_id (INT), route_id(INT), weight (INT)

SELECT r.ost_id, s.title FROM route_r r LEFT JOIN stop s ON (r.ost_id=s.ost_id) WHERE r.route_id='???' SORT BY r.weight ;

Сразу говорю: LEFT JOIN это в случае если остановки с таким номером в базе не будет, оно не крашнет, просто вернет титле как НУЛЛ
244
17 ноября 2011 года
UAS
2.0K / / 19.07.2006
Цитата:
Ну вы даете... Человек просил ПОМОЧЬ отсортировать массивы, а не сказать ему, что он/она не компетентны в проектировании ДБ.

Мы помогаем. Если ошибка сразу в корне - надо сразу это пояснять. Иначе дальше - только хуже.

Цитата:
И че дальше? Я привык такие задачи на С решать. Может на ПХП и есть вариант попроще. Решай, коли такой умный:

А ко мне какие предъявы-то? Вы один из тех людей, который считает, что язык определяющее свойство? Коли незнаете особенностей языка, то нечего тут мне что-то предъявлять. Я написал разумный вариант. Или раз, изучив решение только в рамках С, вы его будете применять и в Java, и в Лиспе?
Задача может быть по-разному решена в разных языках. Ваше решение для конкретного языка - неверное, о чём я и сказал.

Цитата:
Заметь, вес одной остановки повторяется

В рамках задачи - это неверно. Под остановками понимается порядок станций. Если вес одинаковый, то станции тоже одинаковы. Иначе как две остановки могут быть в одной точке?

И напоследок. Вы привыкайте, что здесь на форуме так резко говорят. Такова специфика. Тут ещё товарищ RussianSpy не отписался - он бы вообще написал ещё жестче)

49K
17 ноября 2011 года
vorobej
129 / / 17.11.2011
Цитата:
А ко мне какие предъявы-то? Вы один из тех людей, который считает, что язык определяющее свойство? Коли незнаете особенностей языка, то нечего тут мне что-то предъявлять. Я написал разумный вариант.



Не никаких предъяв сорри. Полностью с вами согласен. Я и правда не знал про ксорт. Ночью выдал по привычку решение, которое сто раз в универе делал на уроках Алгоритмики.

Цитата:
И напоследок. Вы привыкайте, что здесь на форуме так резко говорят. Такова специфика. Тут ещё товарищ RussianSpy не отписался - он бы вообще написал ещё жестче)



Уже привыкаю =) Резко, но справедливо.

76K
18 ноября 2011 года
reddd
2 / / 16.11.2011
Всем большое спасибо! Все сделал, использовал функцию array_multisort

p.s. vorobej - отдельное спасибо
244
18 ноября 2011 года
UAS
2.0K / / 19.07.2006
Хех, а про мультисорт я и сам забыл =)
Но, в общем, это не панацея, но об этом уже все сказано)
49K
18 ноября 2011 года
vorobej
129 / / 17.11.2011
Всегда пожалуйста ;)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог