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.

Rachit
la source
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 .

Jakub Truneček
la source
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!

angoru
la source
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'));
Iryna Batvina
la source
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);

reflexiv
la source
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 ) 
amurrell
la source
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)); 
BEJGAM SHIVA PRASAD
la source
@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;
}
voodoo417
la source
7

Voici une doublure pour le même,

$pic_square = $userdb[array_search($uid,array_column($userdb, 'uid'))]['pic_square'];
Rahul
la source
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

En colère 84
la source
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

M.suleman Khan
la source
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;
}
csi_bern
la source
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;
}
Ahad Ali
la source
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
//        )
//
// )
Serhat
la source
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);
serghei
la source
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;
 }
 ?>
Maurizio Ricci
la source
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;
}}
Whendy Takashy
la source
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;
    }
}
PravinS
la source
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.

sandeep sharma
la source
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!"

Mike Q
la source
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";
        }
    }
 }
Bhavyesh
la source
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));
Yuvraj Singh Shekhawat
la source
0

ma solution:

function searchArrayForField($array, $field, $value) {
    $i = 0;
    foreach ($array as &$row) {
        if ($row[$field] === $value) {
            return $i;
        }
        $i++
    }
    return '';
}
costamatrix
la source