Pencarian array multidimensi PHP berdasarkan nilai

332

Saya memiliki larik tempat saya ingin mencari uid dan mendapatkan kunci array.

Contohnya

Asumsikan kita memiliki array 2 dimensi berikut:

$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'
    )
);

Panggilan fungsi search_by_uid(100)(pengguna pertama) harus kembali 0.

Panggilan fungsi search_by_uid(40489)harus kembali 2.

Saya mencoba membuat loop, tetapi saya ingin kode eksekusi lebih cepat.

Rachit
sumber
menariknya, garis bawah (dan lowdash) pustakawan menambahkan fungsi ini ke javascript ...
ErichBSchulz
9
Saya menulis naskah untuk menguji kinerja beberapa jawaban. Ini menghasilkan array array 500k-anggota dan mencari nilai di anggota terakhir. Saya membandingkan fungsi seperti jawaban yang diterima, dengan dua array_columnjawaban satu-liner. Saya memodifikasi semuanya untuk mengembalikan array yang ditemukan sebenarnya, bukan hanya kuncinya, karena biasanya itulah use case saya. Metode fungsi mencetak 0,361, cari-col 0,184 dan kunci-col 0,189 rata-rata penundaan mikro lebih dari 1000 berjalan untuk setiap metode.
Josh

Jawaban:

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

Ini akan bekerja Anda harus menyebutnya seperti ini:

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

Penting untuk diketahui bahwa jika Anda menggunakan ===jenis yang dibandingkan operator harus persis sama, dalam contoh ini Anda harus mencari stringatau hanya menggunakan ==saja ===.

Berdasarkan jawaban angoru . Di versi PHP yang lebih baru ( >= 5.5.0) Anda bisa menggunakan satu-liner.

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

Berikut adalah dokumentasi: http://php.net/manual/en/function.array-column.php .

Jakub Truneček
sumber
8
Anda juga harus dapat melakukan ini tanpa PHP 5.5 dalam satu liner menggunakan array_map di tempat array_column. Ganti saja array_column($userdb, 'uid')denganarray_map(function($v){return $v['uid'];},$userdb)
Jesse Green
1
Ya kamu benar. Fungsi Lambda tersedia sejak PHP 5.3. dan lebih baik array_search, bukan?
Jakub Truneček
@ Nangoru Saya pikir solusi asli ( foreachloop) akan bekerja lebih cepat karena berhenti segera setelah kecocokan ditemukan. Solusi yang lebih baru harus mengulangi seluruh array sekali untuk mengekstrak array_column, lalu mengulanginya untuk kedua kalinya untuk melakukan pencarian (sampai menemukan kecocokan). Solusi yang lebih baru lebih mudah dibaca, lebih ringkas, tetapi OP secara khusus mengangkat kinerja sebagai masalah
BeetleJuice
@ JakubTruneček. Saya ada hubungannya dengan array yang sama yang diberikan dalam pertanyaan. Saya ingin nama pengguna dari array dengan mengirimkan id. Function findUserName (40489) harus mengembalikan 'Michael'. Bagaimana mungkin?
Ashok Gujjar
@ JakubTruneček Hai saya telah menghadapi masalah ini dalam kode saya tetapi saya memiliki hal yang sangat berbeda. Dalam kasus saya, nilai 'uid' hadir beberapa kali jadi saya perlu mendapatkan array dari key yang didirikan.
Bhavin Thummar
314

Jika Anda menggunakan (PHP 5> = 5.5.0) Anda tidak perlu menulis fungsi Anda sendiri untuk melakukan ini, cukup tulis baris ini dan selesai.

Jika Anda ingin satu hasil saja:

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

Untuk banyak hasil

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

Jika Anda memiliki array asosiatif seperti yang ditunjukkan dalam komentar, Anda dapat membuatnya dengan:

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

Jika Anda menggunakan PHP <5.5.0, Anda dapat menggunakan backport ini , terima kasih ramsey!

Pembaruan: Saya telah membuat beberapa tolok ukur sederhana dan bentuk beberapa hasil tampaknya menjadi yang tercepat, bahkan lebih cepat daripada fungsi kustom Jakub!

angoru
sumber
bagaimana jika nilai yang saya cari (dalam contoh ini adalah 40489) muncul lebih dari satu kali dan saya ingin mendapatkan semua kunci yang muncul?
Dimitris Papageorgiou
jika nilai 40489 muncul lebih dari sekali dalam array akankah fungsi mengembalikan array kunci ... ?? @angoru
jishan
Jika Anda menggunakan kasus kedua untuk beberapa hasil, Anda mendapatkan berbagai kunci.
angoru
2
Ini tidak berfungsi untuk saya ketika kunci dalam $ userdb tidak dimulai sebagai 0,1, 2 dll. Dan mengatakan kuncinya adalah 1234.4566 dll. Kunci yang dihasilkan setelah array_search selalu 0,1,2 dan seterusnya pada
Kaushtuv
1
Ini tidak akan bekerja dengan array asosiatif, namun Anda dapat menyiasati seperti: array_search(40489, array_combine(array_keys($userdb), array_column($userdb, 'uid')))
John Mellor
32

Dalam versi PHP yang lebih baru (> = 5.5.0) Anda dapat menggunakan satu-baris ini:

$key = array_search('100', array_column($userdb, 'uid'));
Iryna Batvina
sumber
Cukup masukkan hasil array_column dalam variabel tertentu menghindari array_column dipanggil untuk setiap hasil pada array.
Maykonn
26

Membangun jawaban yang sangat baik dari Jakub , berikut ini adalah pencarian yang lebih umum yang akan memungkinkan kunci untuk ditentukan (tidak hanya untuk uid):

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

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

refleksiv
sumber
Ini sangat membantu, saya merasa seperti saya berada di puncak penyelesaian masalah saya menggunakan solusi ini, tetapi saya masih memiliki beberapa masalah. Bisakah Anda memberikan wawasan? Pertanyaannya dapat ditemukan di sini: stackoverflow.com/questions/28704644/…
jasenmp
19

Saya tahu ini sudah dijawab, tetapi saya menggunakan ini dan menambahkannya sedikit lebih dalam kode saya sehingga Anda tidak hanya mencari dengan uid. Saya hanya ingin membaginya untuk orang lain yang mungkin membutuhkan fungsi itu.

Inilah contoh saya dan harap diingat ini adalah jawaban pertama saya. Saya mengambil array param karena saya hanya perlu mencari satu array spesifik, tetapi Anda dapat dengan mudah menambahkannya. Saya ingin dasarnya mencari lebih dari sekedar uid.

Juga, dalam situasi saya mungkin ada beberapa kunci untuk kembali sebagai hasil pencarian oleh bidang lain yang mungkin tidak unik.

 /**
     * @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;
    }

Kemudian, saya akhirnya menulis ini untuk memungkinkan saya mencari nilai lain dan kunci asosiatif. Jadi contoh pertama saya memungkinkan Anda untuk mencari nilai dalam kunci asosiatif tertentu, dan mengembalikan semua kecocokan.

Contoh kedua ini menunjukkan kepada Anda di mana nilai ('Taylor') ditemukan di kunci asosiatif tertentu (nama depan) DAN nilai lain (benar) ditemukan di kunci asosiatif lain (dipekerjakan), dan mengembalikan semua kecocokan (Kunci di mana orang dengan nama depan 'Taylor' DAN dipekerjakan).

/**
 * @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;
}

Penggunaan fungsi

$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);

Hasil

Array ( [0] => 2 ) 
amurrell
sumber
10

Terlihat array_filter akan menjadi solusi yang cocok untuk ini ...

$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'
        )
);

Kode 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
sumber
@BEJAM SHIVA PRASAD bisakah Anda membantu saya dengan stackoverflow.com/questions/44721195/… ini ?
Berlaku
menunjukkan kesalahan:syntax error, unexpected '=>' (T_DOUBLE_ARROW), expecting ';'
Shihas
Bisakah Anda menyisipkan lebih banyak info yang saya maksud baris dan kode dan struktur array Anda.
BEJGAM SHIVA PRASAD
@ Shihas saya memperbarui jawaban, saya yakin itu akan teratasi.
BEJGAM SHIVA PRASAD
9

Saya memodifikasi salah satu contoh di bawah ini deskripsi fungsi array_search . Fungsi searchItemsByKeymengembalikan semua nilai dengan $ key dari array multidimensi (level N). Mungkin, itu akan bermanfaat bagi seseorang. Contoh:

 $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
)

Kode fungsi:

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

Berikut ini satu liner untuk hal yang sama,

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

Meskipun ini adalah pertanyaan lama dan memiliki jawaban yang diterima, saya pikir saya akan menyarankan satu perubahan pada jawaban yang diterima .. Jadi pertama-tama, saya setuju bahwa jawaban yang diterima benar di sini.

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

Mengganti preset 'uid' dengan parameter dalam fungsi sebagai gantinya, jadi sekarang memanggil kode di bawah ini berarti Anda dapat menggunakan satu fungsi di beberapa jenis array. Perubahan kecil, tetapi satu yang membuat sedikit perbedaan.

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

Contoh Fiddle PHP

Marah 84
sumber
Alasan lain saya menggunakan SOF ... lebih mudah untuk google dan menemukan kode saya sendiri atau sesuatu yang saya ingat .. +1 untuk repositori publik saya sendiri
Angry 84
BTW, Anda mengatur hasilnya nulldan kemudian dalam kode, Anda membandingkannya false.
Taha Paksu
Diperbaiki dengan mengembalikan false sebagai gantinya, tetapi null mungkin lebih baik dalam hal memeriksa boolean
Angry 84
3

Saya ingin memeriksa tha dalam array berikut $arrapakah ada 'abc' ada di sub array atau tidak

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

Maka saya bisa menggunakan ini

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

Saya pikir Ini adalah cara paling sederhana untuk mendefinisikan

M.suleman Khan
sumber
1

Saya harus menggunakan fungsi un yang menemukan setiap elemen dalam array. Jadi saya memodifikasi fungsi yang dilakukan oleh Jakub Truneček sebagai berikut:

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
sumber
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
sumber
1

Anda dapat menggunakan fungsi ini; 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
sumber
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
sumber
1

Coba ini

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

Bagikan saja, mungkin bisa seperti ini.

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
sumber
0

Coba ini juga

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

Dengan bantuan kode di atas, seseorang dapat menemukan data (sebagian cocok) dari kolom apa pun dalam array 2D sehingga id pengguna dapat ditemukan seperti yang dipersyaratkan dalam pertanyaan.

sandeep sharma
sumber
Harap tambahkan frasa untuk menjelaskan mengapa ini menjawab pertanyaan
Lorenz Meyer
Dengan bantuan kode di atas, seseorang dapat menemukan data (sebagian cocok) dari kolom apa pun dalam array 2D sehingga id pengguna dapat ditemukan seperti yang dipersyaratkan dalam pertanyaan
sandeep sharma
0

Memperluas fungsi @mayhem dibuat, contoh ini akan lebih dari pencarian "fuzzy" jika Anda hanya ingin mencocokkan bagian ( sebagian besar ) dari string pencarian:

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

Misalnya nilai dalam array adalah Welcome to New York! dan Anda ingin contoh pertama dari "New York!"

Mike Q
sumber
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
sumber
0

Jika pertanyaan yaitu

$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",
     ],
   ];

Jawab:

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
sumber
0

solusi saya:

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