php - รับดัชนีตัวเลขของอาเรย์แบบเชื่อมโยง


154

ฉันมีอาเรย์แบบเชื่อมโยงและฉันต้องการค้นหาตำแหน่งตัวเลขของคีย์ ฉันสามารถวนรอบอาร์เรย์ด้วยตนเองเพื่อค้นหา แต่มีวิธีที่ดีกว่าในการสร้าง PHP?

$a = array(
  'blue'   => 'nice',
  'car'    => 'fast',
  'number' => 'none'
);

// echo (find numeric index of $a['car']); // output: 1

คำตอบ:


273
echo array_search("car",array_keys($a));

5
PHP รับประกันการเรียงลำดับของอาเรย์แบบเชื่อมโยงหรือไม่?
เควินเบิร์

7
@KevinBurke มันจะไม่เรียงลำดับใหม่จนกว่าคุณจะใช้ฟังก์ชั่นการเรียงลำดับ ไม่แน่ใจว่าคุณกำลังมองหาการรับประกันประเภทใด แต่ไม่เหมือนกับรุ่น JavaScript ที่ไม่มีลำดับแบบสแตติกสำหรับอาร์เรย์ที่เชื่อมโยงกัน
Fosco

6
ดัชนีที่กำหนดโดย "array_keys" จะไม่ตรงกับดัชนีของอาร์เรย์เดิมเสมอไป ตัวอย่างเช่นหากคุณเปลี่ยนอาร์เรย์โดยใช้ "unset" หรือฟังก์ชั่นอื่น ๆ จำนวนหนึ่งจะมีช่องว่างเหลืออยู่ในดัชนีของอาร์เรย์ดั้งเดิม แต่ array_keys จะสร้างอาร์เรย์ใหม่
SEoF

4
งานนี้ไม่ได้ถ้าอาเรย์ผสมสำหรับarray("val1", "val2", "car" => "val3")จะผลิต0ซึ่งเป็นสิ่งที่ผิด ...
Xriuk

สิ่งนี้แตกต่างจากคำตอบของ @ quantamSoup อย่างไร
ลึกลับ


2

  $a = array(
      'blue' => 'nice',
      'car' => 'fast',
      'number' => 'none'
  );  
var_dump(array_search('car', array_keys($a)));
var_dump(array_search('blue', array_keys($a)));
var_dump(array_search('number', array_keys($a)));



2

ในขณะที่คำตอบของ Fosco ไม่ผิดมีกรณีที่จะต้องพิจารณากับเรื่องนี้: อาร์เรย์แบบผสม ลองนึกภาพฉันมีอาร์เรย์ดังนี้

$a = array(
  "nice",
  "car" => "fast",
  "none"
);

ตอนนี้ PHP อนุญาตให้ใช้ไวยากรณ์ประเภทนี้ แต่มีปัญหาหนึ่ง: ถ้าฉันเรียกใช้รหัสของ Fosco ฉันได้รับ0 สิ่งใดที่ไม่ถูกต้องสำหรับฉัน แต่ทำไมจึงเป็นเช่นนั้น
เพราะเมื่อทำเปรียบเทียบระหว่างสตริงและจำนวนเต็มPHP แปลงสตริงจำนวนเต็ม (และนี่คือโง่นะในความคิดของฉัน) ดังนั้นเมื่อarray_search()การค้นหาสำหรับดัชนีจะหยุดที่คนแรกเพราะเห็นได้ชัดว่าเป็นความจริง("car" == 0)
การตั้งค่าarray_search()เป็นโหมดเข้มงวดจะไม่ช่วยแก้ปัญหาได้เพราะarray_search("0", array_keys($a))จะส่งคืนค่าเท็จแม้ว่าองค์ประกอบที่มีดัชนี 0 อยู่
ดังนั้นโซลูชันของฉันเพียงแปลงดัชนีทั้งหมดarray_keys()เป็นสตริงแล้วเปรียบเทียบอย่างถูกต้อง:

echo array_search("car", array_map("strval", array_keys($a)));

พิมพ์1ซึ่งถูกต้อง

แก้ไข:
ตามที่ฌอนชี้ให้เห็นในความคิดเห็นด้านล่างสิ่งเดียวกันจะใช้กับค่าดัชนีถ้าคุณบังเอิญค้นหาดัชนี int เช่นนี้

$a = array(
  "foo" => "bar",
  "nice",
  "car" => "fast",
  "none"
);
$ind = 0;
echo array_search($ind, array_map("strval", array_keys($a)));

คุณจะได้รับ0ซึ่งเป็นสิ่งที่ผิดเสมอดังนั้นวิธีแก้ปัญหาก็คือการแปลงดัชนี (ถ้าคุณใช้ตัวแปร) กับสตริงเช่นนี้:

$ind = 0;
echo array_search((string)$ind, array_map("strval", array_keys($a)));

1
เมื่อส่งตัวแปรคุณควรแปลงมันเป็นสตริงเนื่องจากการส่งผ่านศูนย์ไปยังอาเรย์แบบเชื่อมโยงจะมีผลกระทบเชิงลบเหมือนกัน ตัวอย่างเช่นvar_dump(array_search(0, array_map("strval", array_keys($a))));มักจะส่งออกมากกว่าint (0) bool (false)
Shaun Cockerill

@ShaunCockerill ถูกต้อง! อัปเดตคำตอบของฉันขอบคุณสำหรับการชี้ให้เห็น!
Xriuk

0

วิธีแก้ปัญหาที่ฉันเกิดขึ้นกับ ... อาจไม่มีประสิทธิภาพในการเปรียบเทียบโซลูชันของ Fosco:

 protected function getFirstPosition(array$array, $content, $key = true) {

  $index = 0;
  if ($key) {
   foreach ($array as $key => $value) {
    if ($key == $content) {
     return $index;
    }
    $index++;
   }
  } else {
   foreach ($array as $key => $value) {
    if ($value == $content) {
     return $index;
    }
    $index++;
   }
  }
 }

2
ใช่ PHP มีฟังก์ชันในตัวหลายพันรายการด้วยเหตุผล เหล่านี้มักจะเร็วกว่าตรรกะเทียบเท่าเขียนออกทางยาวในรหัส PHP
Bill Karwin

3
นี่อาจจะเร็วกว่าarray_searchซึ่งจะเรียงลำดับแรกและดังนั้นจึงช้าช้า
Alasdair

อ่า แต่โค้ดที่มีอยู่ในเครื่องนั้นได้รับการคอมไพล์แล้วและการค้นหาส่วนใหญ่จะเป็นการค้นหาแบบไบนารี่
SEoF

0

โซลูชันทั้งหมดที่ยึดตาม array_keys จะไม่ทำงานสำหรับอาร์เรย์แบบผสม โซลูชันนั้นง่าย:

echo array_search($needle,array_keys($haystack), true);

จาก php.net: หากพารามิเตอร์ที่สามเข้มงวดถูกตั้งค่าเป็น TRUE แล้วฟังก์ชัน array_search () จะค้นหาองค์ประกอบที่เหมือนกันในกองหญ้า ซึ่งหมายความว่ามันจะทำการเปรียบเทียบชนิดเข็มอย่างเข้มงวดในกองหญ้าและวัตถุจะต้องเป็นตัวอย่างเดียวกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.