2009-05-13 16 views

Odpowiedz

25

Jeśli masz tablicę 2D, jak w przykładzie, musisz dostosować rzeczy trochę:

function array_search2d($needle, $haystack) { 
    for ($i = 0, $l = count($haystack); $i < $l; ++$i) { 
     if (in_array($needle, $haystack[$i])) return $i; 
    } 
    return false; 
} 

$myArray = array(
    array('username' => 'user1'), 
    array('username' => 'user2') 
); 
$searchTerm = "user1"; 

if (false !== ($pos = array_search2d($searchTerm, $myArray))) { 
    echo $searchTerm . " found at index " . $pos; 
} else { 
    echo "Could not find " . $searchTerm; 
} 

Jeśli chciał szukaj w jednym konkretnym polu, możesz zmienić funkcję na coś podobnego:

function array_search2d_by_field($needle, $haystack, $field) { 
    foreach ($haystack as $index => $innerArray) { 
     if (isset($innerArray[$field]) && $innerArray[$field] === $needle) { 
      return $index; 
     } 
    } 
    return false; 
} 
+2

Zamiast zapętlać tablicę z pętlą for/count - dlaczego nie "foreach ($ haystack jako $ key => $ value)" - również znajdzie to "user1" w dowolnym polu, a nie tylko "username" – gnarf

+0

Oh. OP był nieco niejednoznaczny w odniesieniu do tego aspektu problemu. Będę edytować teraz. – nickf

+0

Bardzo ładne rozwiązanie +1 – nikhil

27

Spójrz na array_search.

Z pliku PHP help:

<?php 
$array = array(0 => 'blue', 1 => 'red', 2 => 'green', 3 => 'red'); 

$key = array_search('green', $array); // $key = 2; 
$key = array_search('red', $array); // $key = 1; 
?> 
+2

to nie będzie działać dla niego, ponieważ ma on tablicę 2D. chociaż ... dziwnie to przyjęto. – nickf

+0

Tak, przepraszam, za wcześnie. Masz pomysł, jak to zrobić z tablicą 2D? – roflwaffle

+1

@nickf, to faktycznie odpowiada na tytuł pytania, że ​​naprawdę nie odpowiada na jego treść. –

2

Być może za pomocą array_filter i array_keys razem pomogą.

Podejście klasowe.

<?php 

class ArraySearch2d { 
    static protected $_key; 
    static protected $_value; 

    static function isMatch($element) 
    { 
    if (!is_array($element)) return false; 
    return $element[self::$_key] == self::$_value; 
    } 

    static function filter(array $arrayToSearch, $key, $value) 
    { 
    if (!is_string($key)) throw new Exception("Array Key must be a string"); 
    self::$_key = $key; 
    self::$_value = $value; 
    return array_filter($arrayToSearch, 'ArraySearch2d::isMatch'); 
    } 

    // to directly answer your question. 
    static function getIndex(array $arrayToSearch, $key, $value) 
    { 
    $matches = self::filter($arrayToSearch, $key, $value); 
    if (!count($matches)) return false; 
    $indexes = array_keys($matches); 
    return $indexes[0]; 
    } 
} 

$array = array("1"=>array('username'=>'user1'), "3"=>array('username'=>'user2')); 

$matches = ArraySearch2d::filter($array, 'username', 'user2'); 
var_dump($matches); 

$indexs = array_keys($matches); 
var_dump($indexs); 

// Demonstrating quick answer: 
echo "Key for first 'username'=>'user1' element is: " 
    .ArraySearch2d::getIndex($array, 'username', 'user1')."\n"; 

Produkuje:

array(1) { 
    [3]=> 
    array(1) { 
    ["username"]=> 
    string(5) "user2" 
    } 
} 
array(1) { 
    [0]=> 
    int(3) 
} 
Key for first 'username'=>'user1' element is: 1 

Bez użycia klas - to daje ten sam wynik:

<?php 
$field="username"; 
$value = "user2"; 

function usernameMatch($element) 
{ 
    global $field, $value; 
    if (!is_array($element)) return false; 
    return $element[$field] == $value; 
} 

function getFirstIndex(array $array) 
{ 
    if (!count($array)) return false; 
    $indexes = array_keys($array); 
    return $indexes[0]; 
} 

$array = array("1"=>array('username'=>'user1'), "3"=>array('username'=>'user2')); 

$matches = array_filter($array, 'usernameMatch'); 
var_dump($matches); 

$indexs = array_keys($matches); 
var_dump($indexs); 


// Demonstrating quick answer - and why you should probably use the class- 
// you don't want to have to remember these "globals" all the time. 
$field = 'username'; 
$value = 'user1'; 

echo "Key for first 'username'=>'user1' element is: " 
    .getFirstIndex(array_filter($array, 'usernameMatch')); 
+0

z pewnością fakt, że potrzebujesz albo zaimplementować klasę, albo użyć globaliów, oznacza, że ​​nie są to świetne podejścia? Jest całkiem możliwe w kilku liniach kodu, jeśli użyjesz pętli. – nickf

+0

Nie pomyślałem o prostym foreach dopóki nie zobaczyłem twojej odpowiedzi :) - Dobra robota – gnarf

6

To byłoby bardzo proste

private function getArrayKey($haystack, $needle) 
{ 
    foreach($haystack as $key => $product) 
    { 
    if ($product['id'] === $needle) 
    return $key; 
    } 

    return false; 
} 
2

Jeśli wiesz, że klucz to username, po prostu użyj tablicy jako parametru wyszukiwania:

$username = 'user1'; 
$key = array_search(array('username' => $username), $array); 
Powiązane problemy