Linux за българи: Форуми

Програмиране => Web development => Темата е започната от: b2l в Feb 11, 2012, 12:49



Титла: PHP: От array към associative array
Публикувано от: b2l в Feb 11, 2012, 12:49
Пример:
Код
GeSHi (PHP):
  1. (
  2.    [0] => id
  3.    [1] => 1
  4.    [2] => sort
  5.    [3] => asc
  6.    [4] => page
  7.    [5] = > 123
  8. )

Да стане:
Код
GeSHi (PHP):
  1. (
  2.    [id] => 1
  3.    [sort] => asc
  4.    [page] => 123
  5. )

Някакви идеи?


Титла: Re: PHP: От array към associative array
Публикувано от: borovaka в Feb 11, 2012, 13:34
Код
GeSHi (PHP):
  1. <?php
  2.  
  3.  
  4. $arrtest = array('id',1,'sort','asc','page',123);
  5.  
  6.  
  7. while (is_array($arrtest) && !empty($arrtest))
  8. $arr2[array_shift($arrtest)] = array_shift($arrtest);
  9.  
  10. echo '<pre>'.print_r($arr2,true).'</pre>';
  11.  
  12. ?>


Титла: Re: PHP: От array към associative array
Публикувано от: ivo3d в Feb 11, 2012, 13:42
Ето и още един вариант

Код
GeSHi (PHP):
  1. $array = array('id', 1, 'sort', 'asc', 'page', 123);
  2. $assoc = array();
  3.  
  4. for ($i = 0; $i < count($array); $i = $i+2) {
  5. $assoc[$array[$i]] = $array[$i+1];
  6. }


Титла: Re: PHP: От array към associative array
Публикувано от: b2l в Feb 11, 2012, 14:03
Благодаря :).


Титла: Re: PHP: От array към associative array
Публикувано от: borovaka в Feb 11, 2012, 14:07
Даже това дето ти го предложих не трябва да е с du ами направо с while, защото ако не се подаде масив ще се обърка така :)
п.с. Сега ще го оправя :)


Титла: Re: PHP: От array към associative array
Публикувано от: Odido в Feb 11, 2012, 18:44
Не съм много добър с php , но според gatakka foreach е много добър за обхождане на масиви.Ето и моето предложение.
Код
GeSHi (PHP):
  1. <?php
  2. $arr=array('id',1,'sort','asc','page',123);
  3.  
  4. foreach($arr as $v=>$k)
  5. {
  6.    foreach ($arr as $k => $kk) {
  7.        echo $kk.'</br>';
  8.    }
  9.  
  10.  
  11. }
  12.  
  13.   ?>


Титла: Re: PHP: От array към associative array
Публикувано от: b2l в Feb 11, 2012, 18:50
@ApucTokpaT примера ти не е верен. Ако някой го прочете само ще се обърка. Другите две предложения вършат работа.


Титла: Re: PHP: От array към associative array
Публикувано от: Odido в Feb 11, 2012, 19:45
Ммда, прав си ,само ги изрежда в последователен ред ,извинявам се....


Титла: Re: PHP: От array към associative array
Публикувано от: neter в Feb 12, 2012, 02:21
За спорта, едно решение без обичайните цикли:
Код
GeSHi (PHP):
  1. <?php
  2. $input = array('id', 1, 'sort', 'asc', 'page', 123);
  3. $inputFlip = array_flip($input);
  4.  
  5. function getOdd ($item) {
  6.    return $item & 1;
  7. }
  8. function getEven ($item) {
  9.    return !($item & 1);
  10. }
  11.  
  12. $keys = array_flip(array_filter($inputFlip, getEven));
  13. $values = array_flip(array_filter($inputFlip, getOdd));
  14.  
  15. $output = array_combine($keys, $values);
  16. ?>


Титла: Re: PHP: От array към associative array
Публикувано от: thecharge в Mar 25, 2012, 02:13
Пример:
Код
GeSHi (PHP):
  1. (
  2.    [0] => id
  3.    [1] => 1
  4.    [2] => sort
  5.    [3] => asc
  6.    [4] => page
  7.    [5] = > 123
  8. )

Да стане:
Код
GeSHi (PHP):
  1. (
  2.    [id] => 1
  3.    [sort] => asc
  4.    [page] => 123
  5. )

Някакви идеи?

Код
GeSHi (PHP):
  1. <?php
  2. $arr = array(
  3.    "id" => 1,
  4.    "sort" => "asc",
  5.    "page"  => 123,
  6. );
  7.  
  8. //проверка става с
  9.   foreach($arr as $key=> $value)
  10.  {
  11.   echo $key.'->'.$value.'<br/>';
  12.  }
  13.  
  14. // или с
  15. var_dump($arr);
  16. ?>
  17.  
  18.  


Титла: Re: PHP: От array към associative array
Публикувано от: b2l в Mar 25, 2012, 18:30
Че то кой пита как става проверката? Аз знам как става проверката...


Титла: Re: PHP: От array към associative array
Публикувано от: edmon в Mar 25, 2012, 22:57
Айде сега да измерите, коя функция е по-ефективна(по-бърза, по-малко натоварваща)

хехехеех


Титла: Re: PHP: От array към associative array
Публикувано от: clovenhoof в Mar 26, 2012, 10:43
Според мен решението на боровака е доста по-бързо от това на нетер.
Благодарение на използваните функции в последното се извършва многократно обхождане и копиране на масиви. Не знам как е реализирано в PHP, но просто няма как да се избегне.
Докато array_shift спокойно става без обхождане на масива.


Титла: Re: PHP: От array към associative array
Публикувано от: neter в Mar 26, 2012, 11:38
Спорен въпрос е дали решението на borovaka или на ivo3d е най-бързо, така че изборът при писане на код е хубаво да падне на някое от тези две решения - не случайно това са стандартните начини за извършване на въпросното действие. Няма нужда да се прави сравнение между тези две решения - натоварването и скоростта ще са толкова близки, че е въпрос на лична преценка на програмиста кое от двете ще му прилегне по-добре в кода. И все пак, не трябва да се забравя, че for и while циклите не са напълно взаимозаменяеми, но в конкретната ситуация няма проблем.
Моето решение е най-бавно (почти двойно по-бавно, което в случая е около 3/10000 разлика, но ако повторим действието много пъти, почти двойната разлика почва да има значение), и както казах, е само за спорта (да попълним и алтернативната графа) или ако по някаква неведома причина програмистът не може или не иска да се обърне към стандартните цикли :)


Титла: Re: PHP: От array към associative array
Публикувано от: b2l в Mar 26, 2012, 11:39
Как се тества бързодействие на php скрипт?


Титла: Re: PHP: От array към associative array
Публикувано от: neter в Mar 26, 2012, 11:54
Как се тества бързодействие на php скрипт?
Аз ползвам този клас
Код
GeSHi (PHP):
  1. <?php
  2.  
  3. class timer
  4. {
  5. var $start;
  6. var $pause_time;
  7.  
  8. /*  start the timer  */
  9. function timer($start = 0)
  10. {
  11. if($start) { $this->start(); }
  12. }
  13.  
  14. /*  start the timer  */
  15. function start()
  16. {
  17. $this->start = $this->get_time();
  18. $this->pause_time = 0;
  19. }
  20.  
  21. /*  pause the timer  */
  22. function pause()
  23. {
  24. $this->pause_time = $this->get_time();
  25. }
  26.  
  27. /*  unpause the timer  */
  28. function unpause()
  29. {
  30. $this->start += ($this->get_time() - $this->pause_time);
  31. $this->pause_time = 0;
  32. }
  33.  
  34. /*  get the current timer value  */
  35. function get($decimals = 8)
  36. {
  37. return round(($this->get_time() - $this->start),$decimals);
  38. }
  39.  
  40. /*  format the time in seconds  */
  41. function get_time()
  42. {
  43. list($usec,$sec) = explode(' ', microtime());
  44. return ((float)$usec + (float)$sec);
  45. }
  46. }
  47.  
  48. ?>
Използва се така
Код
GeSHi (PHP):
  1. <?php
  2.  
  3. include('път/до/файла/с/класа'); //класът може да се плесне и директно на мястото на този include
  4. $timer = new timer(1);
  5.  
  6. ТВОЯТ КОД
  7.  
  8. echo $timer->get();
  9. ?>
Удобството да се прави с клас е, че много лесно можеш да засечеш времето за изпълнение на което и да е парче код, намиращо се между създаването на обекта $timer и извеждането на резултата.


Титла: Re: PHP: От array към associative array
Публикувано от: b2l в Mar 26, 2012, 12:01
@neter много благодаря :).


Титла: Re: PHP: От array към associative array
Публикувано от: clovenhoof в Mar 26, 2012, 12:59
Спорен въпрос е дали решението на borovaka или на ivo3d е най-бързо, така че изборът при писане на код е хубаво да падне на някое от тези две решения - не случайно това са стандартните начини за извършване на въпросното действие. Няма нужда да се прави сравнение между тези две решения - натоварването и скоростта ще са толкова близки, че е въпрос на лична преценка на програмиста кое от двете ще му прилегне по-добре в кода. И все пак, не трябва да се забравя, че for и while циклите не са напълно взаимозаменяеми, но в конкретната ситуация няма проблем.
Моето решение е най-бавно (почти двойно по-бавно, което в случая е около 3/10000 разлика, но ако повторим действието много пъти, почти двойната разлика почва да има значение), и както казах, е само за спорта (да попълним и алтернативната графа) или ако по някаква неведома причина програмистът не може или не иска да се обърне към стандартните цикли :)

Аз сравних твоето решение с това на боровака.
Сега погледнах това на ivo3d и аз лично бих избрал неговото.

В C помня че do/while беше с най-добро бързодействие. Също има значение в предиката дали ще се сравнява с 0 или с някакво число. С 0 е по-бързо. Pre increment e за предпочитане пред post increment. Това обаче за C, а в РНР предполагам тези неща не важат.


Титла: Re: PHP: От array към associative array
Публикувано от: thecharge в Mar 26, 2012, 22:07
Че то кой пита как става проверката? Аз знам как става проверката...
Как се тества бързодействие на php скрипт?
... изтрито ... Какъв е най-елемнтарният скрипт за бързодействие, а имено нещо от сорта на:

Код
GeSHi (PHP):
  1. <?php
  2. $start = microtime();
  3. $start = explode(' ',$start);
  4. $start = $start[1] + $start[0];
  5.  
  6.  
  7.  
  8. //тук се изпълнява скрипта
  9.  
  10.  
  11.  
  12. $end = microtime();
  13. $end = explode(' ',$end);
  14. $end = $end[1] + $end[0];
  15. $response= ($end - $start);
  16. echo number_format($response, 4, '.', '').' секунди';
  17. ?>
  18.  


... изтрито ...
П.С. За по кратко може само:
Код
GeSHi (PHP):
  1. <?php
  2. function measure()
  3. {
  4. $a = microtime();
  5. $a = explode(' ',$a);
  6. $a = $a[1] + $a[0];
  7. return $a;
  8. }
  9. $start = measure();
  10.  
  11.  
  12.  
  13. //тук се изпълнява скрипта
  14.  
  15.  
  16.  
  17.  
  18. $end = measure();
  19. $response= ($end - $start);
  20. echo number_format($response, 4, '.', '').' секунди';
  21. ?>
  22.  


редакция от neter: Редактирано, съгласно т.6 от правилата ($2) на форума


Титла: Re: PHP: От array към associative array
Публикувано от: SmashThePain в May 31, 2012, 23:40
Ако ще се прави с премахване на елементи от масива,  което не е хубава практика, доста по-добре да се ползва pop вместо shift. Ако някой имплементира shift с константно време ще го поздравя. Вероятно хората от PHP им е през оная работа за паметта и имплементацията на shift инкрементира указателя с единица. Такова фрагментиране на паметта е опасно, особено когато се разполага с малко памет...

Премахването на елементи от масиви е много много лоша практика в случая. Това се предполага че ще бъде някаква вълшебна utility функция, която трябва да приема като аргумент масив и на изхода да връща асоциативен масив. Та по идея масивите е хубаво да се предават по референция не по стойност. От тук следва, че ще се модифицират данни на потребителя, което е неприемливо, когато си говорим за API.


Титла: Re: PHP: От array към associative array
Публикувано от: neter в Jun 01, 2012, 01:31
Тъй като в случая става дума за действия с данни, на практика най-доброто, което може да се направи като оптимизация, е процесът да си остане в базата данни (където би трябвало да седят данните), вместо да се извежда в PHP. С това ще постигнем разтоварване на паметта и много по-бърз процес на обработка.
Тъкмо напоследък се занимавам с обработката на една идея, за целите на която имах нужда от скрипт, който да обхожда голямо количество данни. Данните ми седят в MySQL и по инерция списах обхождането на PHP, вземайки си със заявки на части данните, за да ми стигне паметта. Само че се оказа, че така ще отнеме необозримо много време, и докато бях зациклил над варианти как да го оптимизирам, един колега ми зададе хубавия въпрос "А защо не го правиш директно в базата?". Нямах отговор поради каква причина не го правя и реших да пробвам. Резултатът беше, че тестовите данни, с които си пробвам скрипта и които са много по-малко от реалните данни, скриптът с PHP минаваше за 4 минути, а подобен алгоритъм със същите данни, но реализиран със SQL, минаваше за 5 секунди. В крайна сметка (то пак по негова идея) минах на съвсем друг алгоритъм (още по-бърз) за обхождане и от две седмици насам правя обработката на реалните данни, подготвил съм се да приключа след някой и друг месец, и не мога да си представя колко време щеше да му трябва, ако бях останал на реализация с PHP. Както стана дума и в една друга тема, всеки език с целите си. Когато става дума за обхождания на данни, езикът за това е SQL, мястото е базата данни и всяка друга реализация е излишно губене на време и ресурси :)


Титла: Re: PHP: От array към associative array
Публикувано от: Naka в Jun 01, 2012, 10:18
Искам само да добавя, че от това с какъв тип цикъл ще се обхожда масива (for, foreach/while), зависи от това дали индексите в източника масив ще са подредени и поредни.
например  при това индексите вървят 0,1,2,3,4,5....:
Код:
 [0] => id
 [1] => 1
 [2] => sort
 [3] => asc
 [4] => page
 [5] = > 123
и затова може да се обхожда с for ($i = 0; $i < count($array); $i = $i+2)

но такъв масив спокойно може да изглежда и така:
Код:
 [0] => id
 [1] => 1
 [3] => sort
 [5] => asc
 [444] => page
 [445] = > 123
тогава такова обхождане с 'for' би било неправилно. Но ако се обхожда с  'foreach' или 'while' няма да има проблеми.
Много пъти ми се е случвало входящият масив да се получава в резултат на някакви предварителни обработки и да нямам 100% сигурност, че индексите ще са подредени и поредни. Затова най-сигурното е обхождане с 'foreach' или 'while' . В php всички масива са асоциативни. И входящият масив също ти е  асоциативен.

 


Титла: Re: PHP: От array към associative array
Публикувано от: SmashThePain в Jun 01, 2012, 11:24
@Naka това само в език от високо ниво може да стане. Няма ясно разграничаване между масив и хеш таблица. Ако правя API за масиви, проблемът със sparse arrays няма да е мой проблем. Ако някой подава подобни масиви има сериозен проблем с четенето и разбирането на API-то.

Итераторите като foreach обикновенно са доста по-тежки от един нормален for цикъл. За PHP не мога да говоря в дълбочина, но за JavaScript мога. Та в JavaScript енджините имат оптимизации когато говорим за обхождане с for цикъл и последователни числови индекси. Същото ако го направиш с for-in цикъл нещата ще двойно по-бани.
В примера тук дори for цикъла може да се оптимизира, като се кешира стойността на `count' вместо да се извиква на всяка итерация.

Щях да те питам, кога ти се е налагало да итерираш масив с разбъркани индекси?


Титла: Re: PHP: От array към associative array
Публикувано от: VladSun в Jun 22, 2012, 22:14
Код
GeSHi (PHP):
  1. function get($key, &$input) {
  2.  $keys = array_flip($input);
  3.  return $input[$keys[$key] + 1];
  4. }
  5.  


Титла: Re: PHP: От array към associative array
Публикувано от: VladSun в Jun 25, 2012, 23:14
Всъщност не е добра идея - потребителски дефинираната информация може да "презапише" ключовете при array_flip(). Освен това array_flip би могла предизвика E_NOTICE за невалидните ключове дефинирани от информационната част.


Титла: Re: PHP: От array към associative array
Публикувано от: nask00 в Jul 12, 2012, 17:23
Как се тества бързодействие на php скрипт?
С time() ;)