[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: специфично
andrey888
Мужики , есть следующая специфическая задача которую нужно решить самым простым (из возможных) способом .
Имеется поле в БД следующего содержания
$10-$20,$21-$50,$51-$100

Нужно проверить в какой из представленных промежутков входит число пришедшее от юзера .
То есть посредством php скорее всего нужно сначала отчистить всю это строку от знака доллар , затем сделать explode через запятую и получаем примерно следующее

$test[0]='10-20'
$test[1]='21-50'
$test[2]='51-100'
и затем нам нужно установить в какой из частей массива (по номеру) наш верный промежуток , то есть другими словами какая из частей массива является верным интервалом для нашего числа.
Во первых ,верной ли дорогой пошел товарищи ? может есть способы гораздно проще реализовать такое .
Во вторых ,если верно то как лучше найти нужный интервал (= нужную часть массива)..

Спасибо .




Спустя 18 минут, 15 секунд (19.10.2011 - 20:58) imbalance_hero написал(а):
andrey888
А зачем ты в таком виде хранишь? 2 отдельных поля, min и max, при выборке так и пишешь, SELECT ... WHERE `min` <= $num ORDER BY `min` DESC LIMIT 1, будет как раз выборка этого поля.
Даже в таком случае второй показать MAX не нужен.

Спустя 1 минута, 52 секунды (19.10.2011 - 21:00) imbalance_hero написал(а):
Конечно можно было бы в мускуле сделать обработку с внутренней обработкой, типо взять данные до -, и их сгруппировать и выбрать значение, но зачем такое извращение, когда можно банально сделать 2 поля.

Спустя 1 час, 13 минут, 3 секунды (19.10.2011 - 22:13) andrey888 написал(а):
Извращение потому что хранить мин и макс не представляется возможным .. всю ситтуацию обрисовывать не стану но поверте на слово если б можно было хранить в более простом виде - никаких проблем бы не было ) .. такое поле не одно и каждое такое поле находится в связке с другими , поэтому если разбивать для каждого значения $10 - одно поле, $20 - другое , то получится таблица из нескольких десятков колонок , а если учитывать еще и их связки - то вообще ТЬМА непролазная ... вообщем это самый простой вариант , теперь просто думаю как проще сделать ту проверку которую я описал выше ..
В мускуле обработка с вложенной обработкой и еще с вложенной обработкой ) - думал насчет этого - но представляется мне что в мускуле убрать ненужные символы и привести все это к сьедобному виду будет намного мудреннее чем в php ..
Думал так же про JavaScript - но видимо самый простой вариант будет именно на пхп
Спасибо за ответы.

Спустя 25 минут, 14 секунд (19.10.2011 - 22:39) Игорь_Vasinsky написал(а):
Ну начало у тя есть

Далее

$count = 12; //Число юзеров

foreach($test as $key => $limit)
{
if($count <= $limit) //сравнили с $count
$need = $key; // высчитали ключ элемента массива $test
}

if($need)
{
$index = $test[$need]; //тут у тя например 10-20
}


Вот у тя и один из нужных

$test[0]=10-20;
$test[1]=21-50;
$test[2]=51-100;


терь осталось найти этот интервал в БД (придётся так же - вырезать $)

Спустя 7 минут, 37 секунд (19.10.2011 - 22:46) imbalance_hero написал(а):
andrey888
Мне кажется, что проблема как раз в построении БД, а не в том, что ты разбиваешь поле на 2 части.
Есть ещё substr, только длину надо знать четкую каждого из значений, тогда можно считать только по первым числам.

Спустя 2 минуты, 40 секунд (19.10.2011 - 22:49) Игорь_Vasinsky написал(а):
я уже привык что обращаются с неправильными структурами БД и уже устал делать акцент на этом.

Когда нить да них до самих дойдёт - вопрос ресурсоёмкости и нормализации

Спустя 3 минуты, 14 секунд (19.10.2011 - 22:52) Игорь_Vasinsky написал(а):
imbalance_hero
Есть ещё substr, только длину надо знать четкую каждого из значений, тогда можно считать только по первым числам.


а можно просто regexp массив забивать, но мне кажется дороже выжет

типа preg_match_all

#(\d{1,}\-\d{1,})#

Спустя 13 минут, 11 секунд (19.10.2011 - 23:05) imbalance_hero написал(а):
Игорь_Vasinsky
Я думаю, даже от substr будет бед много, если таблица большая. Так что регулярку даже советовать не стал через REGEXP smile.gif

Спустя 6 минут, 36 секунд (19.10.2011 - 23:12) Игорь_Vasinsky написал(а):
да тут помойму - вешать-так вешать.... biggrin.gif

Спустя 26 минут, 32 секунды (19.10.2011 - 23:38) Winston написал(а):
Как-то так?
Свернутый текст
$str = '$10-$20,$21-$50,$24-$75,$51-$100';
$num = 25;
$str = str_replace('$', '', $str);
$arr = explode(',', $str);
$res = array_map(create_function('$item', '
global $num;
$inter = explode("-", $item);
if($num >= $inter[0] && $num <= $inter[1])
echo "Число $num входит в интервал " . $item . "<br/>";
else
echo "Число $num не входит в интервал " . $item . "<br/>";
'
), $arr);


Если у тебя PHP >= 5.3 то такое решение будет лучше
Свернутый текст
$str = '$10-$20,$21-$50,$24-$75,$51-$100';
$num = 25;
$str = str_replace('$', '', $str);
$arr = explode(',', $str);
$res = array_map(function($item) use ($num){
$inter = explode("-", $item);
if($num >= $inter[0] && $num <= $inter[1])
echo "Число $num входит в интервал " . $item . "<br/>";
else
echo "Число $num не входит в интервал " . $item . "<br/>";
}, $arr);

Спустя 13 минут (19.10.2011 - 23:51) Игорь_Vasinsky написал(а):
Цитата
use ($num)


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

Спустя 2 минуты, 16 секунд (19.10.2011 - 23:54) Winston написал(а):
Цитата (Игорь_Vasinsky @ 19.10.2011 - 23:51)
позволяет дополнительные аргументы использовать?

А самому попробовать? smile.gif
Конечно позволяет.

Спустя 3 минуты, 3 секунды (19.10.2011 - 23:57) Игорь_Vasinsky написал(а):
ща уже поздно.. но надо срочно внедрять в свои дела такие моменты. wink.gif

Спустя 1 день, 11 часов, 46 минут, 8 секунд (21.10.2011 - 11:43) andrey888 написал(а):
Спасибо за овтеты . сделал следующее

function GetPer($doll,$depar,$refar,$payp,$user,$prid,$frcbar,$rercbar,$uid){
$inter='N/F';
for($d=0;$d<=count($depar)-1;$d++){
if(strstr($depar[$d],'-')){
$test=explode('-',$depar[$d]);
for($dd=0;$dd<=count($test);$dd++){
if(count($test)>1){
if($doll>=$test[0] && $doll<=$test[1]){
$found=$depar[$d]; $inter=$d;
}
}
else{if($doll==$test){$found=$depar[$d]; $inter=$d;} }
}
}
else{
$test=$depar[$d];
if($doll==$test){$found=$depar[$d]; $inter=$d;}
}
}

//unset($doll);unset($depar);unset($test);unset($d);unset($dd);
//return $inter;

$perc=$doll*$refar[$inter]/100;
if(CheckPer($payp,$user,$prid,$uid)==1){ $perc=$perc*$frcbar[$inter]/100; $perc=round($perc,2); return $perc; }else{ $perc=$perc*$rercbar[$inter]/100; $perc=round($perc,2); return $perc; }
}


все отлично работает . А теперь по поводу ресурсоемкости .. Еще раз могу сказать что если разделить мои элементы по базе данных в отдельных колонках (для каждого своя колонка) чтоб впоследствии обращатся к базе и с помощью простеших операций решать мою задачу - ТО в базе вместо 10 колонок было бы 80 (минимум), и даже не учитывая связки между ними я в глубоком сомнении что это было бы правильнее с точки зрения ресурсоемкости.. Но так как я не проверял - утвержать не буду .
А вот теперь вопрос - как проверить ресурсоемкость моей функции ? по времени или еще как нибудь .. не разу не проверял - поэтому не знаю как это делается . Результаты с радостью покажу здесь . Самому интересно .

Спустя 1 час, 57 минут, 15 секунд (21.10.2011 - 13:40) imbalance_hero написал(а):
andrey888
Это относится к первой правильной форме БД, не надо объединять значения для того, чтобы сократить запись. Ты выграешь в размере, и потеряешь в производительности и возможности легко управлять данными.

Спустя 8 минут, 28 секунд (21.10.2011 - 13:49) Игорь_Vasinsky написал(а):
в начале кода

$start = microtime(true);


в конце кода

$end = microtime(true);

echo $end - $start . 'сек';

echo memory_get_usage() / 1024 . 'кб памяти'

Спустя 5 часов, 5 минут, 48 секунд (21.10.2011 - 18:54) andrey888 написал(а):
imbalance_hero понял тебя .. так всегда и делаю , и тоже считаю что лучше сделать нормальную и удобную базу чтоб потом не изобретать велосипед в коде .. Но в данной конкретной ситтуации другого выхода не видел .
Игорь_Vasinsky поставил в начало и конец функции . время от 0.0002..... до 0.0004..... насчет
memory_usage() - выдал Undefined function .... проверяю на локале - может поэтому .

Спустя 4 минуты (21.10.2011 - 18:58) Winston написал(а):
Цитата (andrey888 @ 21.10.2011 - 18:54)
memory_usage() - выдал Undefined function .... проверяю на локале - может поэтому .

Такой ф-и нету. Есть memory_get_usage()

Спустя 4 минуты, 36 секунд (21.10.2011 - 19:03) Игорь_Vasinsky написал(а):
Цитата
Такой ф-и нету. Есть memory_get_usage()


упс... надо было проверить.... biggrin.gif

Спустя 2 минуты, 50 секунд (21.10.2011 - 19:06) andrey888 написал(а):
поставил в конце функции , не знаю с какого момента она начинает свой подсчет ,но выдало 443.6171875кб памяти.

Спустя 43 секунды (21.10.2011 - 19:06) Игорь_Vasinsky написал(а):
на локалке?

Спустя 44 минуты, 8 секунд (21.10.2011 - 19:51) andrey888 написал(а):
да .. надо на реальном сервере ?

Спустя 1 минута, 59 секунд (21.10.2011 - 19:53) Игорь_Vasinsky написал(а):
просто разница будет... во всяком случае у меня была.

Спустя 20 минут, 38 секунд (21.10.2011 - 20:13) andrey888 написал(а):
ну да , думаю на реальном это будет чуток больше .. но те данные которые я получил . Это норма я надеюсь ? ...

Спустя 5 минут, 14 секунд (21.10.2011 - 20:18) Игорь_Vasinsky написал(а):
У меня наоборот было.. на хосте меньше

и...

echo ($end - $start)*1000 . 'сек';


пропустил...


_____________
Прогноз на следующие 5 лет : Россия, Китай - две величайшие державы.
США в Ж*пе. Справедливость восторжествует. )
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.