คุณทำดัชนีอาร์เรย์อีกครั้งใน PHP ได้อย่างไร


157

ฉันมีอาเรย์ต่อไปนี้ซึ่งฉันต้องการจะทำดัชนีใหม่ดังนั้นคีย์จะกลับด้าน (เริ่มจากที่ 1):

อาร์เรย์ปัจจุบัน ( แก้ไข:อาร์เรย์มีลักษณะเช่นนี้):

Array (

[2] => Object
    (
        [title] => Section
        [linked] => 1
    )

[1] => Object
    (
        [title] => Sub-Section
        [linked] => 1
    )

[0] => Object
    (
        [title] => Sub-Sub-Section
        [linked] => 
    )

)

มันควรเป็นอย่างไร:

Array (

[1] => Object
    (
        [title] => Section
        [linked] => 1
    )

[2] => Object
    (
        [title] => Sub-Section
        [linked] => 1
    )

[3] => Object
    (
        [title] => Sub-Sub-Section
        [linked] => 
    )

)

1
มีบางสิ่งที่ตรงกันข้าม?
Gumbo

ดูการแก้ไขของฉันเป็นตัวอย่างแรก
meleyal

และทำไมคุณต้องการดัชนีองค์ประกอบแรกเป็น 1 เพียงแค่เรื่องรูปแบบหรือการประมวลผลภายใน?
Gumbo

มันจะถูกนำมาใช้เป็นพารามิเตอร์สำหรับฟังก์ชั่นที่จะได้รับส่วน URL บางอย่างเช่น get_url_segment (1) จะกลับมาเช่นในหน้านี้ "คำถาม"
meleyal

คำตอบ:


445

หากคุณต้องการจัดทำดัชนีใหม่ที่เริ่มต้นที่ศูนย์ให้ทำดังต่อไปนี้:

$iZero = array_values($arr);

หากคุณต้องการให้เริ่มต้นที่หนึ่งใช้ต่อไปนี้:

$iOne = array_combine(range(1, count($arr)), array_values($arr));

นี่คือหน้าคู่มือสำหรับฟังก์ชั่นที่ใช้:


1
คุณควรใช้ range (0, count ($ arr) - 1) เพื่อให้คุณได้อาร์เรย์ที่ไม่มีดัชนี
Max Hartshorn

มันยอดเยี่ยมมากหรือคุณสามารถลองใช้ array_unshift ($ arr, '') เพื่อเพิ่มองค์ประกอบที่ไม่มีการทำดัชนีแล้วยกเลิกการตั้งค่า ($ arr [0]) เพื่อลบออกดังนั้นจึงย้ายดัชนีทั้งหมดทีละรายการ มันอาจเร็วกว่า array_combine () หรือไม่ :)
Steve Horvath

โปรดทราบว่าarray_valuesส่งคืนสำเนาของอาร์เรย์ ดังนั้นถ้าคุณมีการอ้างอิงไปยังอาร์เรย์แล้วarray_spliceจะดีกว่า ดูโซลูชัน @imagiro
Nux

เพียง แต่array_values()ทำให้มันทำงานได้ถ้าคุณเริ่มต้นด้วยดัชนี 0 ตลอดเวลา
kishor10d

55

นี่คือวิธีที่ดีที่สุด :

# Array
$array = array('tomato', '', 'apple', 'melon', 'cherry', '', '', 'banana');

ที่ส่งคืน

Array
(
    [0] => tomato
    [1] => 
    [2] => apple
    [3] => melon
    [4] => cherry
    [5] => 
    [6] => 
    [7] => banana
)

โดยการทำสิ่งนี้

$array = array_values(array_filter($array));

คุณได้รับสิ่งนี้

Array
(
    [0] => tomato
    [1] => apple
    [2] => melon
    [3] => cherry
    [4] => banana
)

คำอธิบาย

array_values() : ส่งคืนค่าของอินพุตอาร์เรย์และดัชนีเป็นตัวเลข

array_filter(): กรององค์ประกอบของอาร์เรย์ที่มีฟังก์ชั่นที่ผู้ใช้กำหนด (UDF ถ้าไม่มีให้บริการ , รายการทั้งหมดในตารางการป้อนข้อมูลมูลค่า FALSE จะถูกลบ .)


3
หากคุณไม่สนใจคำสั่งซื้อคุณสามารถเรียงลำดับ ($ array) ได้
Peter M. Elias

array_filter()ดูเหมือนจะไม่เกี่ยวข้องกับข้อมูลตัวอย่างทั้งหมด
mickmackusa

13

ฉันเพิ่งค้นพบว่าคุณยังสามารถทำ

array_splice($ar, 0, 0);

นั่นคือการทำดัชนีใหม่ในสถานที่ดังนั้นคุณจะไม่จบลงด้วยสำเนาของอาร์เรย์เดิม


9

ทำไมต้องทำดัชนีใหม่ เพียงเพิ่ม 1 ในดัชนี:

foreach ($array as $key => $val) {
    echo $key + 1, '<br>';
}

แก้ไข    หลังจากคำถามได้รับการชี้แจงแล้ว: คุณสามารถใช้array_valuesเพื่อรีเซ็ตดัชนีเริ่มต้นที่ 0 จากนั้นคุณสามารถใช้อัลกอริทึมด้านบนหากคุณต้องการให้องค์ประกอบที่พิมพ์เริ่มต้นที่ 1


คำตอบที่มีคำตอบไม่ถูกต้องสำหรับคำถามนี้ :)
244

6

ฉันอยากจะคิดว่าไม่ว่าเป้าหมายของคุณคืออะไรคุณไม่จำเป็นต้องปรับเปลี่ยนอาร์เรย์ให้เป็นแบบ 1-based แทนที่จะเป็นแบบ 0 แต่สามารถจัดการได้ในเวลาทำซ้ำเช่น Gumbo ที่โพสต์

อย่างไรก็ตามเพื่อตอบคำถามของคุณฟังก์ชั่นนี้ควรแปลงอาร์เรย์ใด ๆ ให้เป็นเวอร์ชันที่ใช้ 1

function convertToOneBased( $arr )
{
    return array_combine( range( 1, count( $arr ) ), array_values( $arr ) );
}

แก้ไข

นี่คือฟังก์ชั่นที่ใช้ซ้ำได้ / ยืดหยุ่นมากขึ้นถ้าคุณต้องการ

$arr = array( 'a', 'b', 'c' );

echo '<pre>';
print_r( reIndexArray( $arr ) );
print_r( reIndexArray( $arr, 1 ) );
print_r( reIndexArray( $arr, 2 ) );
print_r( reIndexArray( $arr, 10 ) );
print_r( reIndexArray( $arr, -10 ) );
echo '</pre>';

function reIndexArray( $arr, $startAt=0 )
{
    return ( 0 == $startAt )
        ? array_values( $arr )
        : array_combine( range( $startAt, count( $arr ) + ( $startAt - 1 ) ), array_values( $arr ) );
}

5

สิ่งนี้จะทำสิ่งที่คุณต้องการ:

<?php

$array = array(2 => 'a', 1 => 'b', 0 => 'c');

array_unshift($array, false); // Add to the start of the array
$array = array_values($array); // Re-number

// Remove the first index so we start at 1
$array = array_slice($array, 1, count($array), true);

print_r($array); // Array ( [1] => a [2] => b [3] => c ) 

?>

5

คุณอาจต้องการพิจารณาสาเหตุที่คุณต้องการใช้อาร์เรย์แบบ 1 ทั้งหมด อาเรย์ที่ใช้ zero-based (เมื่อใช้อาเรย์ที่ไม่ใช่แบบเชื่อมโยง) เป็นมาตรฐานที่ค่อนข้างดีและหากคุณต้องการส่งออกไปยัง UI ส่วนใหญ่จะจัดการกับโซลูชันโดยเพิ่มจำนวนเต็มเมื่อส่งออกไปยัง UI

คิดถึงความมั่นคงทั้งในแอปพลิเคชันของคุณและในรหัสที่คุณทำงานด้วยเมื่อคิดถึงดัชนีที่อิงกับ 1 สำหรับอาร์เรย์


2
สิ่งนี้สัมพันธ์โดยตรงกับการแยกระหว่างเลเยอร์ธุรกิจและเลเยอร์การนำเสนอ หากคุณกำลังแก้ไขรหัสในตรรกะของคุณเพื่อรองรับงานนำเสนอคุณกำลังทำสิ่งที่ไม่ดี ตัวอย่างเช่นหากคุณทำเช่นนี้กับคอนโทรลเลอร์คอนโทรลเลอร์ของคุณจะเชื่อมโยงกับตัวแสดงมุมมองเฉพาะแทนที่จะเตรียมข้อมูลสำหรับตัวแสดงมุมมองใด ๆ ที่อาจใช้ (php, json, xml, rss และอื่น ๆ )
Tres


5

คุณสามารถสร้างดัชนีอาร์เรย์ใหม่เพื่อให้อาร์เรย์ใหม่เริ่มต้นด้วยดัชนี 1 เช่นนี้

$arr = array(
  '2' => 'red',
  '1' => 'green',
  '0' => 'blue',
);

$arr1 = array_values($arr);   // Reindex the array starting from 0.
array_unshift($arr1, '');     // Prepend a dummy element to the start of the array.
unset($arr1[0]);              // Kill the dummy element.

print_r($arr);
print_r($arr1);

ผลลัพธ์จากด้านบนคือ

Array
(
    [2] => red
    [1] => green
    [0] => blue
)
Array
(
    [1] => red
    [2] => green
    [3] => blue
)

คุณไม่ต้องใช้array_valuesที่นี่ ดูคำตอบของฉัน
ฝน

4

คล้ายกับ @monowerker ฉันต้องการสร้างดัชนีใหม่อีกครั้งโดยใช้คีย์ของวัตถุ ...

$new = array();
$old = array(
  (object)array('id' => 123),
  (object)array('id' => 456),
  (object)array('id' => 789),
);
print_r($old);

array_walk($old, function($item, $key, &$reindexed_array) {
  $reindexed_array[$item->id] = $item;
}, &$new);

print_r($new);

สิ่งนี้ส่งผลให้:

Array
(
    [0] => stdClass Object
        (
            [id] => 123
        )
    [1] => stdClass Object
        (
            [id] => 456
        )
    [2] => stdClass Object
        (
            [id] => 789
        )
)
Array
(
    [123] => stdClass Object
        (
            [id] => 123
        )
    [456] => stdClass Object
        (
            [id] => 456
        )
    [789] => stdClass Object
        (
            [id] => 789
        )
)


3

หากคุณไม่ได้พยายามจัดลำดับใหม่คุณสามารถทำได้ดังนี้:

$ array = array_reverse ($ array);
$ array = array_reverse ($ array);

array_reverse นั้นเร็วมากและจะเรียงตามที่ย้อนกลับ มีคนอื่นแสดงให้ฉันเห็นเมื่อนานมาแล้ว ดังนั้นฉันไม่สามารถใช้เครดิตสำหรับการมากับมัน แต่มันง่ายและรวดเร็วมาก


2

คล้ายกับการมีส่วนร่วมของ Nick ฉันมาที่โซลูชันเดียวกันสำหรับการทำดัชนีอาร์เรย์อีกครั้ง แต่ปรับปรุงฟังก์ชั่นเล็กน้อยตั้งแต่ PHP รุ่น 5.4 มันไม่ทำงานเนื่องจากการส่งผ่านตัวแปรโดยการอ้างอิง ตัวอย่างฟังก์ชั่นการทำดัชนีใหม่เป็นแบบนี้โดยใช้useการปิดคำหลัก:

function indexArrayByElement($array, $element)
{
    $arrayReindexed = [];
    array_walk(
        $array,
        function ($item, $key) use (&$arrayReindexed, $element) {
            $arrayReindexed[$item[$element]] = $item;
        }
    );
    return $arrayReindexed;
}

1

นี่คือการดำเนินการของฉันเอง คีย์ในอาร์เรย์อินพุตจะถูกกำหนดหมายเลขใหม่ด้วยคีย์ที่เพิ่มขึ้นเริ่มต้นจาก $ start_index

function array_reindex($array, $start_index)
{
    $array = array_values($array);
    $zeros_array = array_fill(0, $start_index, null);
    return array_slice(array_merge($zeros_array, $array), $start_index, null, true);
}


1

คุณสามารถทำได้อย่างง่ายดายหลังจากใช้ array_values ​​() และ array_filter () ฟังก์ชั่นร่วมกันเพื่อลบองค์ประกอบอาร์เรย์ที่ว่างเปล่าและทำดัชนีใหม่จากอาร์เรย์ใน PHP

array_filter () ฟังก์ชั่น PHP array_filter () ฟังก์ชั่นลบองค์ประกอบอาร์เรย์ที่ว่างเปล่าหรือค่าจากอาร์เรย์ใน PHP สิ่งนี้จะลบค่าว่างเปล่าโมฆะเท็จค่า 0 (ศูนย์)

ฟังก์ชัน array_values ​​() PHP array_values ​​() ส่งคืนอาร์เรย์ที่มีค่าทั้งหมดของอาร์เรย์ อาร์เรย์ที่ส่งคืนจะมีแป้นตัวเลขเริ่มต้นที่ 0 และเพิ่มขึ้น 1

ลบองค์ประกอบอาร์เรย์ว่างเปล่าและทำดัชนีใหม่

ก่อนอื่นเรามาดูผลลัพธ์ของ $ stack array:

<?php
  $stack = array("PHP", "HTML", "CSS", "", "JavaScript", null, 0);
  print_r($stack);
?>

เอาท์พุท:

Array
(
    [0] => PHP
    [1] => HTML
    [2] => CSS
    [3] => 
    [4] => JavaScript
    [5] => 
    [6] => 0
)

ในผลลัพธ์ข้างต้นเราต้องการที่จะลบค่าว่างเปล่า, โมฆะ, 0 (ศูนย์) และจากนั้นทำดัชนีองค์ประกอบอาร์เรย์อีกครั้ง ตอนนี้เราจะใช้ array_values ​​() และ array_filter () ฟังก์ชั่นร่วมกันเช่นในตัวอย่างด้านล่าง:

<?php
  $stack = array("PHP", "HTML", "CSS", "", "JavaScript", null, 0);
  print_r(array_values(array_filter($stack)));
?>

เอาท์พุท:

Array
(
    [0] => PHP
    [1] => HTML
    [2] => CSS
    [3] => JavaScript
)

array_filter()ดูเหมือนจะไม่เกี่ยวข้องกับข้อมูลตัวอย่างของ OP อย่างสมบูรณ์
mickmackusa

1

การลบซ้ำและทำดัชนีอาร์เรย์อีกครั้ง:

<?php  
   $oldArray = array('0'=>'php','1'=>'java','2'=>'','3'=>'asp','4'=>'','5'=>'mysql');
   //duplicate removal
   $fillteredArray = array_filter($oldArray);
   //reindexing actually happens  here
   $newArray = array_merge($filteredArray);
   print_r($newArray);
?>

array_filter()ดูเหมือนจะไม่เกี่ยวข้องกับข้อมูลตัวอย่างของ OP อย่างสมบูรณ์
mickmackusa

1

วิธีที่เร็วที่สุดที่ฉันสามารถนึกได้

array_unshift($arr, null);
unset($arr[0]);
print_r($arr);

และถ้าคุณต้องการสร้างดัชนีใหม่อีกครั้ง (เริ่มต้นที่ศูนย์) และคุณมี PHP +7.3 คุณสามารถทำได้ด้วยวิธีนี้

array_unshift($arr);

ฉันเชื่อว่าarray_unshiftดีกว่าarray_valuesเมื่อก่อนไม่สร้างสำเนาของอาร์เรย์


0

รู้สึกเหมือนarray_combine()คำตอบทั้งหมดคือการคัดลอก "ความผิดพลาด" เดียวกัน (การโทรที่ไม่จำเป็นarray_values())

array_combine() ละเว้นคีย์ของพารามิเตอร์ทั้งสองที่ได้รับ

รหัส: ( สาธิต )

$array = [
    2 => (object)['title' => 'Section', 'linked' => 1],
    1 => (object)['title' => 'Sub-Section', 'linked' => 1],
    0 => (object)['title' => 'Sub-Sub-Section', 'linked' => null]
];

var_export(array_combine(range(1, count($array)), $array));

เอาท์พุท:

array (
  1 => 
  (object) array(
     'title' => 'Section',
     'linked' => 1,
  ),
  2 => 
  (object) array(
     'title' => 'Sub-Section',
     'linked' => 1,
  ),
  3 => 
  (object) array(
     'title' => 'Sub-Sub-Section',
     'linked' => NULL,
  ),
)

0

การเรียงลำดับเป็นเพียงการเรียงลำดับ () การทำดัชนีใหม่นั้นดูค่อนข้างโง่ แต่ถ้าจำเป็นก็จะทำเช่นนั้น แม้ว่าจะไม่ได้อยู่ในสถานที่ ใช้array_walk ()หากคุณจะทำสิ่งนี้ในหลาย ๆ ที่เพียงใช้ลูป for-key-value ลูปถ้าเป็นการดำเนินการครั้งเดียว

<?php

function reindex(&$item, $key, &$reindexedarr) {
    $reindexedarr[$key+1] = $item;
}

$arr = Array (2 => 'c', 1 => 'b', 0 => 'a');

sort($arr);
$newarr = Array();
array_walk($arr, reindex, &$newarr);
$arr = $newarr;
print_r($arr); // Array ( [1] => a [2] => b [3] => c )

?>

-10

ถ้ามันตกลงที่จะสร้างอาร์เรย์ใหม่มันคือ:

$result = array();
foreach ( $array as $key => $val )
    $result[ $key+1 ] = $val;

หากคุณต้องการกลับรายการในสถานที่คุณต้องวิ่งไปข้างหลังเพื่อที่คุณจะได้ไม่ต้องกระทืบดัชนีที่คุณต้องการ:

for ( $k = count($array) ; $k-- > 0 ; )
    $result[ $k+1 ] = $result[ $k ];
unset( $array[0] );   // remove the "zero" element

20
คำตอบสำหรับปัญหานี้ไม่ควรวนซ้ำ ส่วนสำคัญของคำตอบคือได้ใช้array_values()จะได้รับอาร์เรย์ 0-based และแล้วทำให้การปรับบางอย่างเพื่อให้ผลว่าถ้าอาร์เรย์ 1 ตามเป็นจริงที่จำเป็น
Grantwparks
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.