2009-05-13 12 views

Répondre

25

Si vous avez un tableau 2D, comme dans votre exemple, vous aurez besoin de personnaliser les choses un peu:

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; 
} 

Si vous vouliez rechercher dans un seul domaine particulier, vous pouvez modifier la fonction à quelque chose comme ceci:

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

Au lieu de boucler le tableau avec la boucle for/count - pourquoi pas "foreach ($ haystack comme $ key => $ value)" - aussi, trouverait "user1" dans n'importe quel champ, pas seulement "username" – gnarf

+0

Oh. Le PO était un peu ambigu sur cet aspect du problème. Je vais éditer maintenant. – nickf

+0

Très belle solution +1 – nikhil

27

Jetez un oeil à array_search.

A partir du fichier d'aide PHP:

<?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

cela ne fonctionnera pas pour lui, car il a un tableau 2D. cependant ... ça a été accepté, étrangement. – nickf

+0

Oui, désolé je l'ai accepté trop tôt. Une idée sur la façon de le faire avec un tableau 2D? – roflwaffle

+1

@nickf, il répond en fait au titre de la question, pensait en effet qu'il ne répondait pas au corps de celui-ci. –

2

Peut-être en utilisant array_filter et array_keys ensemble aidera.

Approche basée sur les classes.

<?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"; 

Produit:

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

Sans l'aide de classes - ce qui produit le même résultat:

<?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

le fait que vous ayez besoin d'implémenter une classe ou d'utiliser des globals signifie que ce ne sont pas de bonnes approches? C'est tout à fait possible dans quelques lignes de code, si vous utilisez simplement une boucle. – nickf

+0

N'a pas pensé à la simple foreach jusqu'à ce que j'ai vu ta réponse :) - Bon travail – gnarf

6

Ce serait très simple

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

    return false; 
} 
2

Si vous savez que le La touche est username, il suffit d'utiliser un tableau comme paramètre de recherche:

$username = 'user1'; 
$key = array_search(array('username' => $username), $array); 
Questions connexes