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

시작 색인을 0으로 다시 색인하려면 다음을 수행하십시오.

$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, '')을 사용하여 인덱스가없는 요소를 추가 한 다음 unset ($ 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
순서에 신경 쓰지 않는다면 sort ($ 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_values0에서 시작하여 색인을 재설정 할 수 있습니다. 그런 다음 인쇄 된 요소를 1에서 시작하려는 경우 위의 알고리즘을 사용할 수 있습니다.


:)이 질문에 대한 과소 대답
jminkler

6

글쎄, 최종 목표가 무엇이든간에 실제로 0 기반이 아닌 1 기반으로 배열을 수정할 필요는 없지만 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 기반 배열을 사용하려는 이유를 고려할 수도 있습니다. 제로 기반 배열 (비 연관 배열을 사용하는 경우)은 표준이며 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
$tmp = array();
foreach (array_values($array) as $key => $value) {
    $tmp[$key+1] = $value;
}
$array = $tmp;

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

간단히 이렇게하십시오 :

<?php

array_push($array, '');
$array = array_reverse($array);
array_shift($array);

1

array_values ​​()와 array_filter () 함수를 함께 사용하면 빈 배열 요소를 제거하고 PHP의 배열에서 색인을 다시 생성 할 수 있습니다.

array_filter () 함수 PHP array_filter () 함수는 PHP의 배열에서 빈 배열 요소 또는 값을 제거합니다. 공백, 널, 거짓, 0 값도 제거합니다.

array_values ​​() 함수 PHP array_values ​​() 함수는 배열의 모든 값을 포함하는 배열을 반환합니다. 반환 된 배열에는 0부터 시작하여 1 씩 증가하는 숫자 키가 있습니다.

빈 배열 요소 제거 및 재색 인

먼저 $ stack 배열 출력을 보자 :

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

위 출력에서 ​​공백, null, 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);

그리고 배열을 다시 색인화하려면 (0에서 시작) 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

정렬은 단지 sort () 이며, 재색 인화는 약간 어리석은 것처럼 보이지만 필요한 경우이 작업을 수행합니다. 제자리에 없지만. 여러 장소 에서이 작업을 수행 하려면 array_walk ()를 사용하십시오 . 일회성 작업 인 경우 키 값 루프를 사용하십시오.

<?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 기반 배열을 얻는 데 사용 하고 1 기반 배열이 실제로 필요한 경우 그 결과를 조정하는 것입니다 .
grantwparks
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.