Recherche de tableau multidimensionnel PHP par valeur


332

J'ai un tableau où je veux rechercher uidet obtenir la clé du tableau.

Exemples

Supposons que nous ayons le tableau bidimensionnel suivant:

$userdb = array(
    array(
        'uid' => '100',
        'name' => 'Sandra Shush',
        'pic_square' => 'urlof100'
    ),
    array(
        'uid' => '5465',
        'name' => 'Stefanie Mcmohn',
        'pic_square' => 'urlof100'
    ),
    array(
        'uid' => '40489',
        'name' => 'Michael',
        'pic_square' => 'urlof40489'
    )
);

L'appel de fonction search_by_uid(100)(uid du premier utilisateur) doit retourner0 .

L'appel de fonction search_by_uid(40489)doit retourner2 .

J'ai essayé de faire des boucles, mais je veux un code d'exécution plus rapide.


Fait intéressant, les librarires de soulignement (et de tiret bas) ajoutent cette fonction au javascript ...
ErichBSchulz

9
J'ai écrit un script pour tester les performances de quelques-unes des réponses. Il génère un tableau de tableaux de 500 000 membres et recherche dans celui-ci une valeur dans le dernier membre. J'ai comparé une fonction comme la réponse acceptée, aux deux array_columnréponses unilatérales. Je les ai tous modifiés pour renvoyer le tableau découvert, pas seulement la clé, car c'est généralement mon cas d'utilisation. La méthode de fonction a obtenu 0,361, le micro-retard moyen de recherche-col 0,184 et le col-clés 0,189 sur 1000 exécutions pour chaque méthode.
Josh

Réponses:


474
function searchForId($id, $array) {
   foreach ($array as $key => $val) {
       if ($val['uid'] === $id) {
           return $key;
       }
   }
   return null;
}

Cela fonctionnera. Vous devriez l'appeler comme ceci:

$id = searchForId('100', $userdb);

Il est important de savoir que si vous utilisez des ===types d'opérateurs comparés doivent être exactement les mêmes, dans cet exemple, vous devez rechercher stringou simplement utiliser à la ==place ===.

Basé sur la réponse angoru . Dans les versions ultérieures de PHP ( >= 5.5.0), vous pouvez utiliser une ligne.

$key = array_search('100', array_column($userdb, 'uid'));

Voici la documentation: http://php.net/manual/en/function.array-column.php .


8
Vous devriez également pouvoir le faire sans PHP 5.5 dans une seule ligne en utilisant array_map à la place de array_column. Il suffit de remplacer array_column($userdb, 'uid')pararray_map(function($v){return $v['uid'];},$userdb)
Jesse Green

1
Oui, tu as raison. Les fonctions Lambda sont disponibles depuis PHP 5.3. et mieux c'est array_search, non?
Jakub Truneček

@angoru Je pense que la solution d'origine (la foreachboucle) fonctionnera plus rapidement car elle s'arrête dès qu'une correspondance est trouvée. La nouvelle solution doit parcourir une fois l'ensemble du tableau pour extraire array_column, puis la parcourir une deuxième fois pour effectuer la recherche (jusqu'à ce qu'elle trouve une correspondance). La nouvelle solution est plus facile à lire, plus concise, mais l'OP a spécifiquement
évoqué

@ JakubTruneček. J'ai quelque chose à voir avec le même tableau donné dans la question. Je veux le nom d'utilisateur du tableau en passant id. La fonction findUserName (40489) doit renvoyer 'Michael'. Comment c'est possible?
Ashok Gujjar

@ JakubTruneček Salut, j'ai rencontré ce problème dans mon code, mais j'ai une chose très différente. Dans mon cas, la valeur 'uid' est présente plusieurs fois, j'ai donc besoin d'obtenir un tableau de clés fondées.
Bhavin Thummar

314

Si vous utilisez (PHP 5> = 5.5.0), vous n'avez pas à écrire votre propre fonction pour ce faire, écrivez simplement cette ligne et c'est fait.

Si vous voulez un seul résultat:

$key = array_search(40489, array_column($userdb, 'uid'));

Pour plusieurs résultats

$keys = array_keys(array_column($userdb, 'uid'), 40489);

Dans le cas où vous avez un tableau associatif comme indiqué dans les commentaires, vous pouvez le faire avec:

$keys = array_keys(array_combine(array_keys($userdb), array_column($userdb, 'uid')),40489);

Si vous utilisez PHP <5.5.0, vous pouvez utiliser ce backport , merci ramsey!

Mise à jour: j'ai fait quelques benchmarks simples et le formulaire de résultats multiples semble être le plus rapide, encore plus rapide que la fonction personnalisée Jakub!


que faire si la valeur que je recherche (dans cet exemple est 40489) apparaît plus d'une fois et que je veux obtenir toutes les clés qui y apparaissent?
Dimitris Papageorgiou

si la valeur 40489 apparaît plus d'une fois dans le tableau, la fonction retournera un tableau de clés ... ?? @angoru
jishan

Si vous utilisez le deuxième cas pour plusieurs résultats, vous obtenez un tableau de clés.
angoru

2
Cela n'a pas fonctionné pour moi lorsque la clé dans $ userdb n'a pas commencé comme 0,1, 2 etc. et disons que la clé est 1234,4566 etc. Les clés résultantes après la array_search sont toujours 0,1,2 et ainsi le
Kaushtuv

1
Cela ne fonctionnera pas avec un tableau associatif, mais vous pouvez contourner cela comme ceci: array_search(40489, array_combine(array_keys($userdb), array_column($userdb, 'uid')))
John Mellor

32

Dans les versions ultérieures de PHP (> = 5.5.0), vous pouvez utiliser ce one-liner:

$key = array_search('100', array_column($userdb, 'uid'));

Mettez simplement array_column result dans une variable spécifique en évitant que array_column soit appelé pour chaque résultat sur le tableau.
Maykonn

26

En s'appuyant sur l' excellente réponse de Jakub , voici une recherche plus généralisée qui permettra de spécifier la clé (pas seulement pour uid):

function searcharray($value, $key, $array) {
   foreach ($array as $k => $val) {
       if ($val[$key] == $value) {
           return $k;
       }
   }
   return null;
}

Usage: $results = searcharray('searchvalue', searchkey, $array);


C'est très utile, je sens que je suis sur le point de résoudre mon problème en utilisant cette solution mais j'ai toujours un problème. Pourriez-vous peut-être nous donner un aperçu? La question peut être trouvée ici: stackoverflow.com/questions/28704644/…
jasenmp

19

Je sais que cela a déjà été répondu, mais je l'ai utilisé et je l'ai étendu un peu plus dans mon code afin que vous n'ayez pas à rechercher uniquement par l'uid. Je veux juste le partager pour toute autre personne qui pourrait avoir besoin de cette fonctionnalité.

Voici mon exemple et veuillez garder à l'esprit que c'est ma première réponse. J'ai retiré le tableau de paramètres parce que je n'avais besoin que de rechercher un tableau spécifique, mais vous pouvez facilement l'ajouter. Je voulais essentiellement rechercher plus que juste l'uid.

De plus, dans ma situation, il peut y avoir plusieurs clés à retourner à la suite d'une recherche par d'autres champs qui peuvent ne pas être uniques.

 /**
     * @param array multidimensional 
     * @param string value to search for, ie a specific field name like name_first
     * @param string associative key to find it in, ie field_name
     * 
     * @return array keys.
     */
     function search_revisions($dataArray, $search_value, $key_to_search) {
        // This function will search the revisions for a certain value
        // related to the associative key you are looking for.
        $keys = array();
        foreach ($dataArray as $key => $cur_value) {
            if ($cur_value[$key_to_search] == $search_value) {
                $keys[] = $key;
            }
        }
        return $keys;
    }

Plus tard, j'ai fini par écrire ceci pour me permettre de rechercher une autre valeur et clé associative. Mon premier exemple vous permet donc de rechercher une valeur dans n'importe quelle clé associative spécifique et de renvoyer toutes les correspondances.

Ce deuxième exemple vous montre où une valeur ('Taylor') se trouve dans une certaine clé associative (prénom) ET une autre valeur (true) se trouve dans une autre clé associative (employée), et renvoie toutes les correspondances (Clés où les personnes avec un prénom 'Taylor' ET sont employés).

/**
 * @param array multidimensional 
 * @param string $search_value The value to search for, ie a specific 'Taylor'
 * @param string $key_to_search The associative key to find it in, ie first_name
 * @param string $other_matching_key The associative key to find in the matches for employed
 * @param string $other_matching_value The value to find in that matching associative key, ie true
 * 
 * @return array keys, ie all the people with the first name 'Taylor' that are employed.
 */
 function search_revisions($dataArray, $search_value, $key_to_search, $other_matching_value = null, $other_matching_key = null) {
    // This function will search the revisions for a certain value
    // related to the associative key you are looking for.
    $keys = array();
    foreach ($dataArray as $key => $cur_value) {
        if ($cur_value[$key_to_search] == $search_value) {
            if (isset($other_matching_key) && isset($other_matching_value)) {
                if ($cur_value[$other_matching_key] == $other_matching_value) {
                    $keys[] = $key;
                }
            } else {
                // I must keep in mind that some searches may have multiple
                // matches and others would not, so leave it open with no continues.
                $keys[] = $key;
            }
        }
    }
    return $keys;
}

Utilisation de la fonction

$data = array(
    array(
        'cust_group' => 6,
        'price' => 13.21,
        'price_qty' => 5
    ),
    array(
        'cust_group' => 8,
        'price' => 15.25,
        'price_qty' => 4
    ),
    array(
        'cust_group' => 8,
        'price' => 12.75,
        'price_qty' => 10
    )
);

$findKey = search_revisions($data,'8', 'cust_group', '10', 'price_qty');
print_r($findKey);

Résultat

Array ( [0] => 2 ) 

10

Looks array_filter sera une solution appropriée pour cela ...

$userdb=Array
(
    (0) => Array
        (
            (uid) => '100',
            (name) => 'Sandra Shush',
            (url) => 'urlof100'
        ),

    (1) => Array
        (
            (uid) => '5465',
            (name) => 'Stefanie Mcmohn',
            (pic_square) => 'urlof100'
        ),

    (2) => Array
        (
            (uid) => '40489',
            (name) => 'Michael',
            (pic_square) => 'urlof40489'
        )
);

Code PHP

<?php 
$search = 5465;
$found = array_filter($userdb,function($v,$k) use ($search){
  return $v['uid'] == $search;
},ARRAY_FILTER_USE_BOTH) // With latest PHP third parameter is mandatory.. Available Values:- ARRAY_FILTER_USE_BOTH OR ARRAY_FILTER_USE_KEY  

$values= print_r(array_value($found)); 
$keys =  print_r(array_keys($found)); 

@BEJAM SHIVA PRASAD pourriez-vous s'il vous plaît m'aider avec ce stackoverflow.com/questions/44721195/… ?
Valay

affiche une erreur:syntax error, unexpected '=>' (T_DOUBLE_ARROW), expecting ';'
Shihas

Pouvez-vous s'il vous plaît coller plus d'informations, je veux dire quelle ligne et votre code et la structure du tableau.
BEJGAM SHIVA PRASAD

@Shihas J'ai mis à jour la réponse, je suis sûr qu'elle sera résolue.
BEJGAM SHIVA PRASAD

9

J'ai modifié l'un des exemples ci-dessous description fonction array_search . La fonction searchItemsByKeyrenvoie toutes les valeurs par clé $ à partir du tableau multidimensionnel (N niveaux). Peut-être que ce serait utile pour quelqu'un. Exemple:

 $arr = array(
     'XXX'=>array(
               'YYY'=> array(
                    'AAA'=> array(
                          'keyN' =>'value1'
                   )
               ),
              'ZZZ'=> array(
                    'BBB'=> array(
                          'keyN' => 'value2'
                   )
               )
              //.....
           )
);


$result = searchItemsByKey($arr,'keyN');

print '<pre>';
print_r($result);
print '<pre>';
// OUTPUT
Array
(
  [0] => value1
  [1] => value2
)

Code de fonction:

function searchItemsByKey($array, $key)
{
   $results = array();

  if (is_array($array))
  {
    if (isset($array[$key]) && key($array)==$key)
        $results[] = $array[$key];

    foreach ($array as $sub_array)
        $results = array_merge($results, searchItemsByKey($sub_array, $key));
  }

 return  $results;
}

7

Voici une doublure pour le même,

$pic_square = $userdb[array_search($uid,array_column($userdb, 'uid'))]['pic_square'];

3

Même si c'est une vieille question et a une réponse acceptée, j'ai pensé suggérer un changement à la réponse acceptée. Donc tout d'abord, je suis d'accord que la réponse acceptée est correcte ici.

function searchArrayKeyVal($sKey, $id, $array) {
   foreach ($array as $key => $val) {
       if ($val[$sKey] == $id) {
           return $key;
       }
   }
   return false;
}

Remplacer le 'uid' prédéfini par un paramètre dans la fonction à la place, donc maintenant appeler le code ci-dessous signifie que vous pouvez utiliser la fonction unique sur plusieurs types de tableaux. Petit changement, mais qui fait la légère différence.

    // Array Data Of Users
$userdb = array (
    array ('uid' => '100','name' => 'Sandra Shush','url' => 'urlof100' ),
    array ('uid' => '5465','name' => 'Stefanie Mcmohn','url' => 'urlof100' ),
    array ('uid' => '40489','name' => 'Michael','url' => 'urlof40489' ),
);

// Obtain The Key Of The Array
$arrayKey = searchArrayKeyVal("uid", '100', $userdb);
if ($arrayKey!==false) {
    echo "Search Result: ", $userdb[$arrayKey]['name'];
} else {
    echo "Search Result can not be found";
}

Exemple de PHP Fiddle


Une autre raison pour laquelle j'utilise SOF ... plus facile pour google et trouver mon propre code ou quelque chose dont je me souviens .. +1 pour mon propre référentiel public
Angry 84

BTW, vous définissez le résultat sur nullpuis dans le code, vous le comparez à false.
Taha Paksu

Corrigé en renvoyant false à la place, mais null pourrait être mieux au cas où vérifier les booléens
Angry 84

3

Je veux vérifier que dans le tableau suivant $arrexiste-t-il ou non 'abc' dans les sous-tableaux

$arr = array(
    array(
        'title' => 'abc'
    )
);

Ensuite, je peux utiliser cela

$res = array_search('abc', array_column($arr, 'title'));
if($res == ''){
    echo 'exists';
} else {
    echo 'notExists';
}

Je pense que c'est la façon la plus simple de définir


1

J'ai dû utiliser une fonction qui trouve tous les éléments d'un tableau. J'ai donc modifié la fonction effectuée par Jakub Truneček comme suit:

function search_in_array_r($needle, $array) {
    $found = array();
    foreach ($array as $key => $val) {
        if ($val[1] == $needle) {
            array_push($found, $val[1]);
        }
    }
    if (count($found) != 0)
        return $found;
    else
        return null;
}

1
/**
 * searches a simple as well as multi dimension array
 * @param type $needle
 * @param type $haystack
 * @return boolean
 */
public static function in_array_multi($needle, $haystack){
    $needle = trim($needle);
    if(!is_array($haystack))
        return False;

    foreach($haystack as $key=>$value){
        if(is_array($value)){
            if(self::in_array_multi($needle, $value))
                return True;
            else
               self::in_array_multi($needle, $value);
        }
        else
        if(trim($value) === trim($needle)){//visibility fix//
            error_log("$value === $needle setting visibility to 1 hidden");
            return True;
        }
    }

    return False;
}

1

vous pouvez utiliser cette fonction; https://github.com/serhatozles/ArrayAdvancedSearch

<?php 
include('ArraySearch.php');

$query = "a='Example World' and b>='2'";

$Array = array(
'a' => array('d' => '2'),
array('a' => 'Example World','b' => '2'),
array('c' => '3'), array('d' => '4'),
);

$Result = ArraySearch($Array,$query,1);

echo '<pre>';
print_r($Result);
echo '</pre>'; 

// Output:
// Array
// (
//    [0] => Array
//        (
//            [a] => Example World
//            [b] => 2
//        )
//
// )

1
$a = ['x' => ['eee', 'ccc'], 'b' => ['zzz']];

$found = null;
$search = 'eee';

array_walk($a, function ($k, $v) use ($search, &$found) {
    if (in_array($search, $k)) {
        $found = $v;
    }
});

var_dump($found);

1

Essaye ça

<?php
 function recursive_array_search($needle,$haystack) {
    foreach($haystack as $key=>$value) {
        $current_key=$key;
        if($needle===$value OR (is_array($value) && 
            recursive_array_search($needle,$value) !== false)) {
             return $current_key;
        }
    }
    return false;
 }
 ?>

1

Il suffit de partager, peut-être peut-être comme ça.

if( ! function_exists('arraySearchMulti')){
function arraySearchMulti($search,$key,$array,$returnKey=false)
{
    foreach ($array as $k => $val) {
        if (isset($val[$key])) {
            if ((string)$val[$key] == (string)$search) {
                return ($returnKey ? $k : $val);
            }
        }else{
            return (is_array($val) ? arraySearchMulti($search,$key,$val,$returnKey) : null);
        }
    }
    return null;
}}

0

Essayez aussi

function search_in_array($srchvalue, $array)
{
    if (is_array($array) && count($array) > 0)
    {
        $foundkey = array_search($srchvalue, $array);
        if ($foundkey === FALSE)
        {
            foreach ($array as $key => $value)
            {
                if (is_array($value) && count($value) > 0)
                {
                    $foundkey = search_in_array($srchvalue, $value);
                    if ($foundkey != FALSE)
                        return $foundkey;
                }
            }
        }
        else
            return $foundkey;
    }
}

0
for( $i =0; $i < sizeof($allUsers); $i++)
    {   
    $NEEDLE1='firstname';
    $NEEDLE2='emailAddress';
    $sterm='Tofind';
     if(isset($allUsers[$i][$NEEDLE1]) && isset($allUsers[$i][$NEEDLE2])
        {
            $Fname= $allUsers[$i][$NEEDLE1];
            $Lname= $allUsers[$i][$NEEDLE2];

            $pos1 = stripos($Fname, $sterm);
            $pos2=stripos($Lname, $sterm);//not case sensitive 

            if($pos1 !== false ||$pos2 !== false)
            {$resultsMatched[] =$allUsers[$i];}
            else
            {   continue;}              
        }

}
Print_r($resultsMatched); //will give array for matched values even partially matched

Avec l'aide du code ci-dessus, on peut trouver toutes les données (partiellement appariées) de n'importe quelle colonne du tableau 2D afin que l'ID utilisateur puisse être trouvé comme requis en question.


Veuillez ajouter une phrase pour expliquer pourquoi cela répond à la question
Lorenz Meyer

avec l'aide du code ci-dessus, on peut trouver toutes les données (partiellement appariées) de n'importe quelle colonne du tableau 2D afin que l'ID utilisateur puisse être trouvé comme requis dans la question
sandeep sharma

0

En développant la fonction créée par @mayhem, cet exemple serait davantage une recherche "floue" au cas où vous voudriez simplement faire correspondre une partie (la plupart ) d'une chaîne de recherche:

 function searchArrayKeyVal($sKey, $id, $array) {
    foreach ($array as $key => $val) {
        if (strpos(strtolower($val[$sKey]), strtolower(trim($id))) !== false) {
            return $key;
        }
    }
         return false;
 }

Par exemple, la valeur dans le tableau est Bienvenue à New York! et vous vouliez la première instance de "New York!"


0
$search1 = 'demo';
$search2 = 'bob';
$arr = array('0' => 'hello','1' => 'test','2' => 'john','3' => array('0' => 'martin', '1' => 'bob'),'4' => 'demo');
foreach ($arr as $value) { 
    if (is_array($value)) { 
        if (in_array($search2, $value)) { 
            echo "successsfully";    
            //execute your code 
        }
    } else {  
        if ($value == $search1) { 
            echo "success";
        }
    }
 }

0

Si question ie

$a = [
     [
       "_id" => "5a96933414d48831a41901f2",
       "discount_amount" => 3.29,
       "discount_id" => "5a92656a14d488570c2c44a2",
     ],
     [
       "_id" => "5a9790fd14d48879cf16a9e8",
       "discount_amount" => 4.53,
       "discount_id" => "5a9265b914d488548513b122",
     ],
     [
       "_id" => "5a98083614d488191304b6c3",
       "discount_amount" => 15.24,
       "discount_id" => "5a92806a14d48858ff5c2ec3",
     ],
     [
       "_id" => "5a982a4914d48824721eafe3",
       "discount_amount" => 45.74,
       "discount_id" => "5a928ce414d488609e73b443",
     ],
    [
       "_id" => "5a982a4914d48824721eafe55",
       "discount_amount" => 10.26,
       "discount_id" => "5a928ce414d488609e73b443",
     ],
   ];

Rép:

function searchForId($id, $array) {
    $did=0;
    $dia=0;
   foreach ($array as $key => $val) {
       if ($val['discount_id'] === $id) {
           $dia +=$val['discount_amount'];
           $did++;
       }
   }
    if($dia != '') {
        echo $dia;
        var_dump($did);
    }
   return null;
};
print_r(searchForId('5a928ce414d488609e73b443',$a));

0

ma solution:

function searchArrayForField($array, $field, $value) {
    $i = 0;
    foreach ($array as &$row) {
        if ($row[$field] === $value) {
            return $i;
        }
        $i++
    }
    return '';
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.