Определить ключ двумерного массива по известным значениям

Avenus

Under Glory Yield
Определить ключ двумерного массива по известным значениям

Из базы mysql были выбраны строки удовлетворяющие условию и данные переведены в массив.
PHP:
$obj_res=mysql_query('select ID,NAME,X,Y from TABLE');
$s=0;
while($objs[$s]=mysql_fetch_assoc($obj_res)) $s++;
$objs=array_splice($objs,0,count($objs)-1);
mysql_free_result($obj_res);
Т.е. имеется теперь двумерный массив $objs.

Просьба помочь сделать условие проверки для определеня ключа массива $objs по уже известным значениям X и Y.

К примеру: i=3, j=7 (и в массиве с ключом 4 есть такие значения $objs[4]['X']=3 и $objs[4]['Y']=7)

Как узнать этот ключ массива $objs, у которого значения X=i и Y=j?
Или может есть способ все это сделать иначе?
 

Mr_Max

Первый класс. Зимние каникулы ^_^
Команда форума
Зачем?

-~{}~ 18.08.07 20:07:

Для чего?
что хотите реализовать?
 

Avenus

Under Glory Yield
Уже реализовано, только очень плохо. Строится таблица 19х19 через двойной цикл: внешний i=1..19 и внутренний j=1..19. И на каждом значении i,j происходит запрос из базы mysql по условию
PHP:
where X=i and Y=j
Вот и переделываю, чтобы сделать один запрос, а потом при построении таблицы сравнивать значения полученного массива от запроса со значениями цикла i,j.
 

Mr_Max

Первый класс. Зимние каникулы ^_^
Команда форума
Avenus
Если я правильно Вас понял то
на мой взгляд самое простое решение это
$check_data[$data['X']][$data['Y']]

Но стОит ли
облегчать жизнь БД и усложнять ПХП...?
 

Avenus

Under Glory Yield
Нагрузка на сервер преваышает предел, который установлен хостером (1.8% vs 1%). Поступило требование от хостера: либо снизить нагрузку, либо они заблокируют аккаунт.
Поняли правильно, но как конкретно это условие написать под мой пример?
 

Mr_Max

Первый класс. Зимние каникулы ^_^
Команда форума
Avenus
Нагрузка на сервер преваышает предел, который установлен хостером (1.8% vs 1%). Поступило требование от хостера: либо снизить нагрузку, либо они заблокируют аккаунт.
Хм
Тарифный план хостинг-провайдер не меняет? :)
 

Avenus

Under Glory Yield
Вроде такого (это, конечно, не работает):
PHP:
for($i=1;$i<=19;$i++){
  for($j=1;$j<=19;$j++){
     if( $objs[?]['X']==$i && $objs[?]['Y']==$j){
//     ... в табилицу пишется значение $objs[?]['NAME']
//     ? - как раз ключ, который не знаю как узнать 
     }
  }
}
-~{}~ 18.08.07 21:28:

:) можно поменять, но нагрузка не изменяется (на всех 1%)
Поменять хостинг тоже не хочется, т.к. когда значения почти во всех ячейках таблицы и эта таблица генерится у 3-ех посетителей сайта - нагрузка сразу вырастает до 2.2%.
Что же будет при 10 посетителях? :(
 

phprus

Moderator
Команда форума
Avenus
оступило требование от хостера: либо снизить нагрузку, либо они заблокируют аккаунт.
Вот с этого и надо было начинать.

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

Кроме того ты чтото не договариваешь, так как постановки задачи не сходятся.
1)
К примеру: i=3, j=7 (и в массиве с ключом 4 есть такие значения $objs[4]['X']=3 и $objs[4]['Y']=7)
и
2)
Строится таблица 19х19 через двойной цикл: внешний i=1..19 и внутренний j=1..19. И на каждом значении i,j происходит запрос из базы mysql по условию
where X=i and Y=j
Во втором случае исходя из запроса X всегда равен индексу i (как я понял номеру строки), а Y всегда равен j (как я понял номеру столбца)

НО в первом случае у тебя X != i и Y != j.

Если второй вариант постановки задачи верный, то извлекай записи по условию where X >= 1 and X <= 19 and Y >= 1 and Y <= 19 и размещай записи в свой массив используя в качестве индекса i поле X, а в качестве индекса j поле Y.
 

Avenus

Under Glory Yield
:) Да нет же, ошибки нет. Я в точности переписал, что делал. Ничего не недоговаривал. Т.е. Вы предлагаете все равно делать запросы из базы во время цикла?
Кстати, только что решил проблему таким образом:
Написал отдельную функцию:
PHP:
function find_obj($objs,$i,$j){
$exist='';
foreach($objs as $obj) if($obj['X']==$i&&$obj['Y']==$j) $exist=$obj;
return $exist;
}
А при построении таблицы в цикле поставил такую проверку:
PHP:
for($i=1;$i<=19;$i++){ 
  for($j=1;$j<=19;$j++){
      $obj=find_obj($objs,$j,$i);
      if($obj){
//    .... здесь происходят действия по записи в таблицу
      }
 } 
}
Но при этом все равно скорость зарпоса около 1 сек (то, что уже есть 2,2 сек). Думаю нагрузка на сервер не очень-то и уменьшится :(

-~{}~ 18.08.07 21:56:

Вернее, не скороть запроса, а скорость генерации страницы.
 

phprus

Moderator
Команда форума
Avenus
Да нет же, ошибки нет.
Не ври. В первом твоем сообщении значения X != i и Y != j, а из второго следует что X == i и Y == j

По этому я предлагаю в один запрос выбрать все записи у которых X находится в диапазоне от 1 до 19 и Y находится в диапазоне от 1 до 19 а потом перебирая результат этого запроса заполнять результирующий массив используя в качестве индексов значения полей X и Y результата. Итог: один запрос и один цикл.

Но при этом все равно скорость зарпоса около 1 сек
Это время выполнения одного запроса??? тогда к моему решению еще нужно добавить этап добавления индексов по полям X и Y.

-~{}~ 19.08.07 00:04:

Кроме того я уверен, что это не самый медленный участок кода в этом скрипте.
 

Avenus

Under Glory Yield
Индексы добавил, стало быстрее. :) Спасибо!
А насчет того, что я обманываю, я не соглашусь...
Если ошибка в коде, может быть... но я этот код скопировал сюда из своего редактора.
В один запрос я и выбираю все записи:
PHP:
$obj_res=mysql_query('select ID,NAME,X,Y from TABLE'); 
$s=0; 
while($objs[$s]=mysql_fetch_assoc($obj_res)) $s++; 
$objs=array_splice($objs,0,count($objs)-1); 
mysql_free_result($obj_res);
Значения X и Y в базе всегда в пределах 1..19.
Но только строк в базе не 19х19=361. А для каждой ситуации по разному. И есть строка с X=3 и Y=7.
При построении таблицы размером 19 на 19:
PHP:
for($i=1;$i<=19;$i++){  
  for($j=1;$j<=19;$j++){ 
// ... в момент когда i=3 и j=7 должно вывестись значение из базы,
// у которого X=3 и Y=7 ($objs[4]['X']=3 и $objs[4]['Y']=7)
// т.е. как я и написал X=i и Y=j
  } 
}
Так где же я вру? :) Вот если бы можно было не перебирать все значения для каждой ячейки, а делать проверку массива $objs на совпадения, тогда было бы отлично!

-~{}~ 18.08.07 22:29:

Я понял, почему Вы подумали, что я вру ....
Ряды из цикла наоборот заполняются :) Из-за этого, блин, и значения в таблице не в том месте появляются!
Но проблема все равно остается.
 

Mr_Max

Первый класс. Зимние каникулы ^_^
Команда форума
а делать проверку массива $objs на совпадения, тогда было бы отлично!
PHP:
$sql = "1 Запрос на выборку."
В цикле while {
    $check_data[$data['X']][$data['Y']]=.........;
}

В Вашем двойном цикле.
for($i=1;$i<=19;$i++){   
  for($j=1;$j<=19;$j++){
  if (isset ($check_data[$i][$j]))
  }  
}
 

Avenus

Under Glory Yield
Все, разобрался, большое спасибо!!! :)
Запрос сделал так:
PHP:
$obj_res=mysql_query('select ID,NAME,X,Y from TABLE');
while($objs=mysql_fetch_assoc($obj_res)) $obj[$objs['X']][$objs['Y']]=$objs;
mysql_free_result($obj_res);
Вывод так:
PHP:
for($j=1;$j<=19;$j++){
 for($i=1;$i<=19;$i++){
   if(isset($obj[$i][$j]){
//   ... действия
   }
 }
}
:) Хотя вначале, я здесь об этом не писал... Я пробовал так сделать, но ерунда какая-то получалась. думал, так не пойдет. Оказывается все даже проще: местами поменять надо было обязательно циклы.
Еще раз спасибо!

-~{}~ 18.08.07 23:14:

Теперь на генерацию таблицы уходит 0.3 сек.
Думаю, что теперь нагрузка на сервер значительно снизится!
 
Сверху