Помогите с очень сложной сортировкой
есть таблица 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
ОЧЕНЬ прошу помочь!
Почитайте про нормализацию баз данных.
1) Эти поля текстовыми быть НЕ должны
2) Каждое значение - отдельная строка. Все хранить через запятую - неверно.
Делайте таблицу с названиями и ID остановок. Делайте таблицу маршрутов, где указываете идентификатор маршрута. Делаете сводную таблицу из полей "id маршрута", "id остановки", "вес остановки".
Все, далее отсортировать ума особо много не надо.
Тут тебе надо про рекурсивные ф-ции почитать.
$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
Нет, не имел. Ему же ещё надо название остановки вывести. Такие задачи должны решаться одним запросом. Пока что решений два: перепроектировать БД, либо писать хранимую процедуру.
А начать надо с нормальных идентификаторов.
И че дальше? Я привык такие задачи на С решать. Может на ПХП и есть вариант попроще. Решай, коли такой умный:
$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_);
Вес не должен повторяться. Хоть и признаюсь, малька ночью перемудрил (я не знал о существовании ксорт, спасибо, все-таки кое чему научил).
Таблица 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 это в случае если остановки с таким номером в базе не будет, оно не крашнет, просто вернет титле как НУЛЛ
Мы помогаем. Если ошибка сразу в корне - надо сразу это пояснять. Иначе дальше - только хуже.
А ко мне какие предъявы-то? Вы один из тех людей, который считает, что язык определяющее свойство? Коли незнаете особенностей языка, то нечего тут мне что-то предъявлять. Я написал разумный вариант. Или раз, изучив решение только в рамках С, вы его будете применять и в Java, и в Лиспе?
Задача может быть по-разному решена в разных языках. Ваше решение для конкретного языка - неверное, о чём я и сказал.
В рамках задачи - это неверно. Под остановками понимается порядок станций. Если вес одинаковый, то станции тоже одинаковы. Иначе как две остановки могут быть в одной точке?
И напоследок. Вы привыкайте, что здесь на форуме так резко говорят. Такова специфика. Тут ещё товарищ RussianSpy не отписался - он бы вообще написал ещё жестче)
Не никаких предъяв сорри. Полностью с вами согласен. Я и правда не знал про ксорт. Ночью выдал по привычку решение, которое сто раз в универе делал на уроках Алгоритмики.
Уже привыкаю =) Резко, но справедливо.
p.s. vorobej - отдельное спасибо
Но, в общем, это не панацея, но об этом уже все сказано)