PHP 日本研討會 2024
新增註解

使用者貢獻的註解 17 則註解

228
turabgarip at gmail dot com
7 年前
關於在多維陣列中搜尋;關於 "xfoxawy at gmail dot com" 的兩個註解;

它與 array_column() (最低 PHP 5.5.0) 結合使用時,可以完美地搜尋多維陣列,但它可能不會傳回您期望的值。

<?php array_search($needle, array_column($array, 'key')); ?>

由於 array_column() 會產生結果陣列;它不會保留多維陣列的鍵。因此,如果您檢查鍵,它將會失敗。

例如:

<?php
$people
= array(
2 => array(
'name' => 'John',
'fav_color' => 'green'
),
5=> array(
'name' => 'Samuel',
'fav_color' => 'blue'
)
);

$found_key = array_search('blue', array_column($people, 'fav_color'));
?>

在這裡,您可能會預期 $found_key 會是 "5",但事實並非如此。它會是 1。因為它是 array_column() 函式所產生陣列的第二個元素。

其次,如果您的陣列很大,我建議您先指定一個新的變數,這樣它就不會為每個搜尋的元素呼叫 array_column()。為了獲得更好的效能,您可以執行:

<?php
$colors
= array_column($people, 'fav_color');
$found_key = array_search('blue', $colors);
?>
53
cue at openxbox dot com
21 年前
如果您在條件陳述式中使用 array_search 的結果,請務必使用 === 運算子而不是 == 來測試是否找到相符項。否則,搜尋具有數字索引的陣列會導致索引 0 始終被評估為 false/null。這個細微差別花了我很多時間和理智,所以我希望這能幫助到某人。如果您不知道我在說什麼,這裡有一個範例

<?php
$code
= array("a", "b", "a", "c", "a", "b", "b"); // 臭名昭著的 abacabb mortal kombat 代碼 :-P

// 這是錯誤的
while (($key = array_search("a", $code)) != NULL)
{
// 無限迴圈,無論是否取消設定
unset($code[$key]);
}

// 這是 _正確的_
while (($key = array_search("a", $code)) !== NULL)
{
// 迴圈將終止
unset($code[$key]);
}
?>
33
stefano@takys dot it
13 年前
為了不區分大小寫的搜尋,最好這樣做

<?php
array_search
(strtolower($element),array_map('strtolower',$array));
?>
15
RichGC
18 年前
為了擴展先前的評論,這裡有一些例子說明
當您想要使用返回的陣列鍵時,在 IF 語句中使用 array_search 可能會出錯的情況。
當您想要使用返回的陣列鍵時,在 IF 語句中使用 array_search 可能會出錯的情況。

假設您想要搜尋以下兩個陣列

<?php
$fruit_array
= array("apple", "pear", "orange");
$fruit_array = array("a" => "apple", "b" => "pear", "c" => "orange");

if (
$i = array_search("apple", $fruit_array))
//問題:第一個陣列返回鍵值 0,而 IF 會將其視為 FALSE

if (is_numeric($i = array_search("apple", $fruit_array)))
//問題:適用於第一個陣列的數字鍵,但對第二個陣列失敗

if ($i = is_numeric(array_search("apple", $fruit_array)))
//問題:以上述錯誤的順序使用會導致 $i 始終等於 1

if ($i = array_search("apple", $fruit_array) !== FALSE)
//問題:明確地使用且沒有額外的括號會導致 $i 始終等於 1

if (($i = array_search("apple", $fruit_array)) !== FALSE)
//正確:適用於兩個陣列,返回它們的鍵
?>
15
maciej at speccode dot com
9 年前
請注意,嚴格模式可以為您節省數小時的時間。

如果您正在搜尋字串,並且有一個 "true" 布林值在其中,您將會得到它作為結果(第一次出現)。範例如下

<?php

$arr
= [
'foo' => 'bar',
'abc' => 'def',
'bool' => true,
'target' => 'xyz'
];

var_dump( array_search( 'xyz', $arr ) ); //bool
var_dump( array_search( 'xyz', $arr, true ) ); //target

?>
8
thinbegin at gmail dot com
6 年前
儘管 PHP 擁有令人驚嘆的陣列函式和處理技巧,我發現自己需要一種方法來取得特定值的完整陣列鍵映射。此函式可以做到這一點,並返回一個陣列,其中包含取得該(第一個)值出現位置的適當鍵。

function array_recursive_search_key_map($needle, $haystack) {
foreach($haystack as $first_level_key=>$value) {
if ($needle === $value) {
return array($first_level_key);
} elseif (is_array($value)) {
$callback = array_recursive_search_key_map($needle, $value);
if ($callback) {
return array_merge(array($first_level_key), $callback);
}
}
}
return false;
}

使用範例
-------------------

$nested_array = $sample_array = array(
'a' => array(
'one' => array ('aaa' => 'apple', 'bbb' => 'berry', 'ccc' => 'cantalope'),
'two' => array ('ddd' => 'dog', 'eee' => 'elephant', 'fff' => 'fox')
),
'b' => array(
'three' => array ('ggg' => 'glad', 'hhh' => 'happy', 'iii' => 'insane'),
'four' => array ('jjj' => 'jim', 'kkk' => 'kim', 'lll' => 'liam')
),
'c' => array(
'five' => array ('mmm' => 'mow', 'nnn' => 'no', 'ooo' => 'ohh'),
'six' => array ('ppp' => 'pidgeon', 'qqq' => 'quail', 'rrr' => 'rooster')
)
);

$search_value = 'insane';

$array_keymap = array_recursive_search_key_map($search_value, $nested_array);

var_dump($array_keymap);
// 輸出
// array(3) {
// [0]=>
// string(1) "b"
// [1]=>
// string(5) "three"
// [2]=>
// string(3) "iii"
//}

----------------------------------------------

但是,再次使用上述解決方案,PHP 在如何動態存取巢狀陣列中特定元素的值方面再次顯得不足。為此,我編寫了第二個函式來提取上面映射的值。

function array_get_nested_value($keymap, $array)
{
$nest_depth = sizeof($keymap);
$value = $array;
for ($i = 0; $i < $nest_depth; $i++) {
$value = $value[$keymap[$i]];
}

return $value;
}

使用範例
-------------------
echo array_get_nested_value($array_keymap, $nested_array); // insane
6
opencart dot ocfilter at gmail dot com
3 年前
小心!

<?php

var_dump
(array_search('needle', [ 0 => 0 ])); // int(0) (!)

var_dump(array_search('needle', [ 0 => 0 ], true)); // bool(false)

?>

但是,在 php 8 中

<?php

var_dump
(array_search('needle', [ 0 => 0 ])); // bool(false)

?>
2
yasien dot dwieb at gmail dot com
4 年前
當使用 array_search 搜尋字串和整數的混合時,請注意鍵的前綴可能會衝突,就像我的情況一樣,我遇到了以下情況

假設您有以下陣列
<?php
$arr
= [
1 => 'index 0',
2 => 'index 1',
3 => 'index 2',
'3anothersuffix' => 'index 3'
];

$index1 = array_search('3', array_keys($arr)); // 2
$index2 = array_search('3anothersuffix', array_keys($arr)); //2
?>

$index1 和 $index2 將會相同

在使用嚴格類型搜尋之後

<?php
$index1
= array_search('3', array_keys($arr), true); // false
$index2 = array_search('3anothersuffix', array_keys($arr), true); //3
?>

它將完全找不到 $index1,同時會為 $index2 返回正確的值;
3
azaozz, gmail
15 年前
擴展 hansen{}cointel.de 的評論

當搜尋字串且陣列包含 0 (零) 時,字串會透過類型轉換轉換為 (int),轉換結果始終為 0(也許相反的行為才是正確的,應該將陣列值 0 轉換為字串)。如果沒有使用嚴格比較,這會產生意想不到的結果

<?php
$a
= array(0, "str1", "str2", "str3");
echo
"
str1 = "
.array_search("str1", $a).",
str2 = "
.array_search("str2", $a).",
str3 = "
.array_search("str3", $a).",

str1 strict = "
.array_search("str1", $a, true).",
str2 strict = "
.array_search("str2", $a, true).",
str3 strict = "
.array_search("str3", $a, true);
?>

這會回傳
str1 = 0, str2 = 0, str3 = 0, str1 strict = 1, str2 strict = 2, str3 strict = 3
3
andreas dot damm at maxmachine dot de
16 年前
結合 array_search() 的語法和 array_keys() 的功能,以取得具有給定搜尋值之陣列的所有 key=>value 關聯。
<?php
function array_search_values( $m_needle, $a_haystack, $b_strict = false){
return
array_intersect_key( $a_haystack, array_flip( array_keys( $a_haystack, $m_needle, $b_strict)));
}
?>

用法
<?php
$array1
= array( 'pre'=>'2', 1, 2, 3, '1', '2', '3', 'post'=>2);
print_r( array_search_values( '2', $array1));
print_r( array_search_values( '2', $array1, true));
print_r( array_search_values( 2, $array1, true));
?>

將回傳
array(4) {
["pre"] =>
string(1) "2"
[1] =>
int(2)
[4] =>
string(1) "2"
["post"] =>
int(2)
}
array(2) {
["pre"] =>
string(1) "2"
[4] =>
string(1) "2"
}
array(2) {
[1] =>
int(2)
["post"] =>
int(2)
}
5
codeslinger at compsalot dot com
15 年前
要非常注意的一件事是,如果 needle 是字串,而陣列本身包含數字和字串的混合值 (甚至是看起來像數字的字串),array_search() 將會失敗。

問題在於,除非您指定「strict」,否則比對是使用 == 進行的,在這種情況下,任何字串都會與數值零比對,這不是您想要的。

-----

此外,PHP 可以非常快速地查閱索引。對於許多情況,維護多個陣列是可行的,其中一個陣列的索引是搜尋鍵,而另一個是包含資料的正常陣列。

<?php

$normal
[$index] = array('key'=>$key, 'data'=>'foo');
$inverse[$key] = $index;

//非常快速的查閱,這勝過任何其他類型的搜尋

if (array_key_exists($key, $inverse))
{
$index = $inverse[$key];
return
$normal[$index];
}

?>
6
n-regen
15 年前
如果您只知道陣列中值的其中一部分,並想知道完整的值,可以使用下列函式
<?php
function array_find($needle, $haystack)
{
foreach (
$haystack as $item)
{
if (
strpos($item, $needle) !== FALSE)
{
return
$item;
break;
}
}
}
?>
此函式會回傳 $haystack 中第一個包含 $needle 的完整值。
1
team at concerty dot com
1 個月前
關於使用 array_column 在多維陣列中搜尋,為了補充 "turabgarip at gmail dot com" 的筆記,以下是尋找正確鍵值的解決方法

$array_column = 'name';
$searchValue = 'my value ;
$result = array_filter($myArray, function ($subarray) use ($array_column, $searchValue) {
return isset($subarray[$array_column]) && $subarray[$array_column] === $searchValue;
});

echo key($result);
0
helenadeus at gmail dot com
15 年前
我試圖使用 array_search 來擷取所有符合給定 needle 的值,但結果只會回傳第一個符合的鍵值。我建立了一個小函式,它與 array_search 的運作方式相同,但會回傳所有符合給定 needle 的鍵值。輸出結果會是一個陣列。

<?php

$haystack
= array('a','b','a','b');

$needle = 'a';

print_r(array_search_all($needle, $haystack));

//輸出將會是
// Array
// (
// [0]=>1
// [1]=>3
// )

function array_search_all($needle, $haystack)
{
#array_search_match($needle, $haystack) 回傳 $haystack 中所有與 $needle 相符的值的鍵值

foreach ($haystack as $k=>$v) {

if(
$haystack[$k]==$needle){

$array[] = $k;
}
}
return (
$array);


}

?>
0
kermes [at] thesevens [dot] net
17 年前
先前搜尋的變體,會回傳符合給定值的鍵值陣列

<?php
function array_ksearch($array, $str)
{
$result = array();
for(
$i = 0; $i < count($array); next($array), $i++)
if(
strtolower(current($array)) == strtolower($str))
array_push($result, key($array);

return
$result;
}
?>

用法如下
<?php
$testArray
= array('one' => 'test1', 'two' => 'test2', 'three' => 'test1', 'four' => 'test2', 'five' => 'test1');
print_r(array_ksearch($testArray, 'test1'));
?>
-1
stooshie at gmail dot com
13 年前
回傳索引而非布林值的遞迴二元搜尋範例。
<?php
// 返回 needle 在 haystack 中的索引
function binSearch($needle, $haystack)
{
// 如果需要計算搜尋深度,才會用到 n
global $n;
$n++;
// 取得傳入陣列的長度
$l = count($haystack);
// 如果長度為 0,則有問題
if($l <= 0)
{
return -
1;
}
// 取得中間元素
$m = (($l+($l%2))/2);
// 如果 mid >= 長度 (例如 l=1)
if($m >= $l)
{
$m = $m-1;
}
// 取得要與傳入元素比較並根據比較結果進行分支的索引元素
$compare = $haystack[$m];
switch(
true)
{
case(
$compare>$needle):
{
// 遞迴處理下半部分
$new_haystack = array_slice($haystack, 0, $m);
$c = count($new_haystack);
$r = binSearch($needle, $new_haystack);
// 返回目前索引 - (下半部分長度 - 在下半部分找到的索引)
return $m - ($c - $r);
break;
}
case(
$compare<$needle):
{
// 遞迴處理上半部分
$new_haystack = array_slice($haystack, $m, ($l-$m));
$c = count($new_haystack);
$r = binSearch($needle, $new_haystack);
// 返回目前位置 + 在上半部分找到的索引
return $m + $r;
break;
}
case(
$compare==$needle):
{
// 找到了,所以返回索引
return $m;
break;
}
}
}
?>
-1
nordseebaer at gmx dot de
4 年前
檢查回傳值是否為 false 非常重要!我使用 array_search() 來判斷一個值的索引,以便取消設定這個值,然後才發現 $arr[false] === $arr[0] !

<?php
$arr
= ['apple', 'banana'];

var_dump($arr[0] === 'apple'); // true
var_dump($arr[false] === $arr[0]); // true
var_dump($arr[false] === 'apple'); // true

unset($arr[array_search('banana', $arr)]); // 索引 = 1
var_dump($arr);

// 結果
// array(1) {
// [0]=>
// string(5) "apple"
// }

unset($arr[array_search('peach', $arr)]); // 找不到,結果是 false
var_dump($arr);

// 結果
// array(0) {
// }
// 因為 $arr[false] === $arr[0]
?>

所以務必檢查 array_search 的回傳值!
To Top