Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > 5,6,7-20,35,100-400,550,549,548


Автор: Wowa 17.4.2005, 10:44
Дана строка: 5,6,7-20,35,100-400,550,549,548
Нужно обработать все элементы с заданными ИД в этом списке и интревалах. По идее, нужно бы это все обработать и закинуть все номера в массив. Но если будет указана строка, типа: 3,4,5,7,100-10000, то получиться, что нужно будет 9004 элемента записывать в массив, что имхо довольно много. А ведь можешь быть еще больше. Как поступить в этом случае, чтобы не заносить все поэлементно в массив, а затем через foreach обрабатывать. Есть какие-нибудь мысли?

Автор: Irokez 17.4.2005, 10:50
я бы сделал так:
1) разбить строку по запятым, получил бы массив: (3 4 5 6 100-10000)
2) циклом foreach пройтись по полученному массиву, определяя является ли элемент числом или же интервалом, если числом, то получить элемент с ID равному заданному числу, если интервалом, то определить границы интервала (регекспом или др строковыми ф-циями) и через цикл while или do .. while совершать операции над элементами с ID, находящимися в полученном интервале

Автор: IZ@TOP 18.4.2005, 08:01
Wowa, а зачем тебе это нужно? Может быть есть более простое решение?

Варианты Ирокеза поддерживаю. Кроме того что цикл foreach нужен smile Можно и for использовать.

Автор: Wowa 18.4.2005, 09:29
Цитата(IZ @ 18.4.2005, 06:01)
Wowa, а зачем тебе это нужно? Может быть есть более простое решение?

Есть база с записями. У каждой записи есть ИД. Мне нужно удалить в ней определенные записи.

Автор: Akina 18.4.2005, 09:50
По методу Irokez-а я бы:

1) без изменений
2) Преобразовать массив из полученного вида в массив типа Start-End, т.е. для указанного случая

3 3
4 4
5 5
6 6
100 10000

Дальше уже работать много проще...

Код

for (i=1; i<n; i++)
{
   for (j=Start(i); j<End(i); j++)
   {
      ...
   }
}

Автор: Wowa 24.4.2005, 11:47
А что сделать быстрее

выполнить N раз это:
Код

DELETE FROM table WHERE id=$i;


или один раз это:
Код

DELETE FROM table WHERE id IN ($array);


?

Автор: Sardar 24.4.2005, 12:03
Цитата(Wowa @ 24.4.2005, 10:47)
или один раз это

Конечно вторым способом.

По вопросу: бьём список на числа и интервалы. Все числа сгруппировать в один IN, а интервалы в несколько OR BETWEEN.

Автор: Sardar 24.4.2005, 12:30
Вот простенький пример за 5 минут, не проверяющий верность интервала(100-5), и не имееющий отрицания(NOT IN, NOT BETWEEN):
Код
/**
* Строку с числами и интервалами в условие SQL.
* @param $s - сама строка
* @param $target  - на кого ссылаемся в условии
*/
function toQueryExpression($s, $target) {
  $s=explode(",", $s);
  $ids=array();
  $ranges="";
  $ret="";

  for($i=0; $i<sizeof($s); $i++) {
    $el=explode("-", $s[$i]);
    if(sizeof($el)==1) $ids[]=$el[0];
    else $ranges.="OR {$target} BETWEEN {$el['0']} AND {$el['1']} ";
  }
  if(sizeof($ids)>0) {
    $ret="{$target} IN(".implode(", ",$ids).") ";
    $ret.=$ranges;
  } else $ret=substr($ranges, 2);
  return $ret;
}

//test
echo toQueryExpression("5,6,7-20,35,100-400,550,549,548", "id"), "<br>";
echo toQueryExpression("2-5, 45-78", "id"), "<br>";
echo toQueryExpression("1,2,3,4,5", "id"), "<br>";

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)