I have an array in php
$arr = array(
array('id' => 1, 'par' => 5),
array('id' => 2, 'par' => 5),
array('id' => 3, 'par' => 5),
array('id' => 4, 'par' => 7),
array('id' => 5, 'par' => 7),
array('id' => 6, 'par' => 7),
array('id' => 7, 'par' => 9),
array('id' => 8, 'par' => 9),
...
);
Can anybody know an effective algorithm to get a first indeks of an element which has property $arr[x]['par'] == 7. How to get the first x from the array containing 2000 elements?
Thank you
I used a binary search
$par = 7;
$a = 0;$i = -1;
$b = count($arr);
while(true) {
if($par == $arr[$a]['par']) { $i = $a; break; }
if($par == $arr[$m]['par']) { $i = $m; break; }
if($par == $arr[$b]['par']) { $i = $b; break; }
if($a == $m || $m == $b) break;
if($arr[$a]['par'] < $par && $par < $arr[$m]['par']) {
$b = $m; $m = floor(($a+$b)/2);
}
if($arr[$m]['par'] < $parent && $parent < $arr[$b]['par']) {
$a = $m; $m = floor(($a+$b)/2);
}
}
That example was more slow, than a $i=0;while($i < $n && $arr[$i]['par'] != $par) $i++; Can be used the array_search instead?
I'm not sure if using an iterator is any faster than doing it by "hand", but you could use a RecursiveArrayIterator - http://php.net/manual/en/class.recursivearrayiterator.php
$arr = array(
array('id' => 1, 'par' => 5),
array('id' => 2, 'par' => 5),
array('id' => 3, 'par' => 5),
array('id' => 4, 'par' => 7),
array('id' => 5, 'par' => 7),
array('id' => 6, 'par' => 7),
array('id' => 7, 'par' => 9),
array('id' => 8, 'par' => 9),
);
$arrayIterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr));
foreach ($arrayIterator as $subKey=>$subValue) {
if ($subKey == 'par' && $subValue == 9) {
$validArray = iterator_to_array($arrayIterator->getSubIterator());
$id = $validArray['id']; // This is your return array
break;
}
}
But, to be honest, doing it by hand would probably be a lot easier to understand and debug, and for 2000 records - why bother with anything more complex than:
foreach($arr as $subArray) {
if ($subArray['par'] == 9) {
$id = $subArray['id'];
break;
}
}
If you were handling more records, or had the popularity of Facebook, then start to get serious. But sometimes keeping it simple is the best way.