문제

양식에 연관 배열이 있습니다 key => value 키가 숫자 값이지만 순차적 숫자 값은 아닙니다. 키는 실제로 ID 번호이고 값은 카운트입니다. 이것은 대부분의 인스턴스에 적합하지만, 배열의 인간 읽을 수있는 이름을 가져오고 값을 변경하지 않고 키에 사용하는 함수를 원합니다.

나는 이것을하는 함수를 보지 못했지만 이전 키와 새로운 키 (둘 다)를 제공하고 배열을 변환해야한다고 가정합니다. 효율적인 방법이 있습니까?

도움이 되었습니까?

해결책

$arr[$newkey] = $arr[$oldkey];
unset($arr[$oldkey]);

다른 팁

이 작업을 수행하고 배열의 순서를 유지하는 방법은 배열 키를 별도의 배열에 넣고 해당 배열의 키를 찾고 교체 한 다음 값과 다시 결합하는 것입니다.

다음은 다음과 같은 기능입니다.

function change_key( $array, $old_key, $new_key ) {

    if( ! array_key_exists( $old_key, $array ) )
        return $array;

    $keys = array_keys( $array );
    $keys[ array_search( $old_key, $keys ) ] = $new_key;

    return array_combine( $keys, $array );
}

당신의 경우 array 데이터베이스 쿼리에서 구축되므로 키를 직접 변경할 수 있습니다. mysql 성명:

대신에

"select ´id´ from ´tablename´..."

다음과 같은 것을 사용하십시오.

"select ´id´ **as NEWNAME** from ´tablename´..."

Kernelm의 답변은 좋지만 주석 (충돌 키)에서 Greg가 제기 한 문제를 피하기 위해 새 배열을 사용하는 것이 더 안전합니다.

$newarr[$newkey] = $oldarr[$oldkey];
$oldarr=$newarr;
unset($newarr);

사람이 읽을 수있는 이름을 ID에 맵핑하는 두 번째 연관 배열을 사용할 수 있습니다. 그것은 또한 많은 관계를 제공 할 것입니다. 그런 다음 다음과 같은 일을하십시오.

echo 'Widgets: ' . $data[$humanreadbleMapping['Widgets']];

새 배열 키의 위치가 이전 제품과 동일하게하려면 다음을 수행 할 수 있습니다.

function change_array_key( $array, $old_key, $new_key) {
    if(!is_array($array)){ print 'You must enter a array as a haystack!'; exit; }
    if(!array_key_exists($old_key, $array)){
        return $array;
    }

    $key_pos = array_search($old_key, array_keys($array));
    $arr_before = array_slice($array, 0, $key_pos);
    $arr_after = array_slice($array, $key_pos + 1);
    $arr_renamed = array($new_key => $array[$old_key]);

    return $arr_before + $arr_renamed + $arr_after;
}

배열이 재귀 인 경우이 기능을 사용할 수 있습니다.이 데이터를 테스트하십시오.

    $datos = array
    (
        '0' => array
            (
                'no' => 1,
                'id_maquina' => 1,
                'id_transaccion' => 1276316093,
                'ultimo_cambio' => 'asdfsaf',
                'fecha_ultimo_mantenimiento' => 1275804000,
                'mecanico_ultimo_mantenimiento' =>'asdfas',
                'fecha_ultima_reparacion' => 1275804000,
                'mecanico_ultima_reparacion' => 'sadfasf',
                'fecha_siguiente_mantenimiento' => 1275804000,
                'fecha_ultima_falla' => 0,
                'total_fallas' => 0,
            ),

        '1' => array
            (
                'no' => 2,
                'id_maquina' => 2,
                'id_transaccion' => 1276494575,
                'ultimo_cambio' => 'xx',
                'fecha_ultimo_mantenimiento' => 1275372000,
                'mecanico_ultimo_mantenimiento' => 'xx',
                'fecha_ultima_reparacion' => 1275458400,
                'mecanico_ultima_reparacion' => 'xx',
                'fecha_siguiente_mantenimiento' => 1275372000,
                'fecha_ultima_falla' => 0,
                'total_fallas' => 0,
            )
    );

기능은 다음과 같습니다.

function changekeyname($array, $newkey, $oldkey)
{
   foreach ($array as $key => $value) 
   {
      if (is_array($value))
         $array[$key] = changekeyname($value,$newkey,$oldkey);
      else
        {
             $array[$newkey] =  $array[$oldkey];    
        }

   }
   unset($array[$oldkey]);          
   return $array;   
}
$array = [
    'old1' => 1
    'old2' => 2
];

$renameMap = [
    'old1' => 'new1',   
    'old2' => 'new2'
];

$array = array_combine(array_map(function($el) use ($renameMap) {
    return $renameMap[$el];
}, array_keys($array)), array_values($array));

/*
$array = [
    'new1' => 1
    'new2' => 2
];
*/

Kernelm의 솔루션을 좋아하지만 잠재적 인 키 충돌을 처리 할 수있는 것이 필요했습니다 (새로운 키가 기존 키와 일치 할 수 있음). 다음은 다음과 같이 생각해 냈습니다.

function swapKeys( &$arr, $origKey, $newKey, &$pendingKeys ) {
    if( !isset( $arr[$newKey] ) ) {
        $arr[$newKey] = $arr[$origKey];
        unset( $arr[$origKey] );
        if( isset( $pendingKeys[$origKey] ) ) {
            // recursion to handle conflicting keys with conflicting keys
            swapKeys( $arr, $pendingKeys[$origKey], $origKey, $pendingKeys );
            unset( $pendingKeys[$origKey] );
        }
    } elseif( $newKey != $origKey ) {
        $pendingKeys[$newKey] = $origKey;
    }
}

그런 다음 다음과 같은 배열을 순환 할 수 있습니다.

$myArray = array( '1970-01-01 00:00:01', '1970-01-01 00:01:00' );
$pendingKeys = array();
foreach( $myArray as $key => $myArrayValue ) {
    // NOTE: strtotime( '1970-01-01 00:00:01' ) = 1 (a conflicting key)
    $timestamp = strtotime( $myArrayValue );
    swapKeys( $myArray, $key, $timestamp, $pendingKeys );
}
// RESULT: $myArray == array( 1=>'1970-01-01 00:00:01', 60=>'1970-01-01 00:01:00' )

다음은이를 달성하기위한 도우미 기능입니다.

/**
 * Helper function to rename array keys.
 */
function _rename_arr_key($oldkey, $newkey, array &$arr) {
    if (array_key_exists($oldkey, $arr)) {
        $arr[$newkey] = $arr[$oldkey];
        unset($arr[$oldkey]);
        return TRUE;
    } else {
        return FALSE;
    }
}

예쁘다 @kernelm 답변.

용법:

_rename_arr_key('oldkey', 'newkey', $my_array);

돌아올 것입니다 진실 성공적인 이름으로, 그렇지 않으면 거짓.

쉬운 물건 :

이 기능은 대상 $ HASH를 수락하고 $ 교체는 또한 해시를 포함합니다. Newkey => Oldkey Associations.

이 기능은 할 것입니다 원래 순서를 보존하십시오, 그러나 매우 큰 (10K 이상의 레코드와 같은) 배열에 문제가있을 수 있습니다. 성능 및 메모리.

function keyRename(array $hash, array $replacements) {
    $new=array();
    foreach($hash as $k=>$v)
    {
        if($ok=array_search($k,$replacements))
            $k=$ok;
        $new[$k]=$v;
    }
    return $new;    
}

이 대체 기능은 동일하게 수행됩니다 훨씬 더 나은 성능 & 메모리 사용, 원래 주문을 잃어 버리는 비용으로 (해시 가능이기 때문에 문제가되지 않아야합니다!)

function keyRename(array $hash, array $replacements) {

    foreach($hash as $k=>$v)
        if($ok=array_search($k,$replacements))
        {
          $hash[$ok]=$v;
          unset($hash[$k]);
        }

    return $hash;       
}

이 코드는 Oldkey를 새로운 코드로 변경하는 데 도움이됩니다.

$i = 0;
$keys_array=array("0"=>"one","1"=>"two");

$keys = array_keys($keys_array);

for($i=0;$i<count($keys);$i++) {
    $keys_array[$keys_array[$i]]=$keys_array[$i];
    unset($keys_array[$i]);
}
print_r($keys_array);

디스플레이처럼

$keys_array=array("one"=>"one","two"=>"two");

이것은 첫 번째 키를 바꾸는 데 효과적입니다.

$a = ['catine' => 'cat', 'canine'  => 'dog'];
$tmpa['feline'] = $a['catine'];
unset($a['catine']);
$a = $tmpa + $a;

그런 다음 print_r ($ a)는 수리 된 사역 어레이를 렌더링합니다.

Array
(
    [feline] => cat
    [canine] => dog
)

이것은 임의의 키를 바꾸는 데 효과적입니다.

$a = ['canine'  => 'dog', 'catine' => 'cat', 'porcine' => 'pig']
$af = array_flip($a)
$af['cat'] = 'feline';
$a = array_flip($af)

print_r ($ a)

Array
(
    [canine] => dog
    [feline] => cat
    [porcine] => pig
)

일반화 된 기능 :

function renameKey($oldkey, $newkey, $array) {
    $val = $array[$oldkey];
    $tmp_A = array_flip($array);
    $tmp_A[$val] = $newkey;

    return array_flip($tmp_A);
}

한 번에 여러 키를 교체하려면 (순서 보존) :

/**
 * Rename keys of an array
 * @param array $array (asoc)
 * @param array $replacement_keys (indexed)
 * @return array
 */
function rename_keys($array, $replacement_keys)  {
      return array_combine($replacement_keys, array_values($array));
}

용법:

$myarr = array("a" => 22, "b" => 144, "c" => 43);
$newkeys = array("x","y","z");
print_r(rename_keys($myarr, $newkeys));
//must return: array("x" => 22, "y" => 144, "z" => 43);

배열의 순서를 변경하지 않고 전체 배열로 작업 할 때 배열 요소의 키를 변경하는 대안적인 방법이 있습니다. 배열을 새 배열로 복사하는 것입니다.

예를 들어, 인덱스 및 연관 키가 포함 된 혼합 된 다차원 배열로 작업하고 있었으며 주문을 중단하지 않고 정수 키를 값으로 바꾸고 싶었습니다.

모든 숫자 배열 항목에 대한 키/값을 전환하여 그렇게했습니다. [ '0'=> 'foo']. 순서는 손상되지 않습니다.

<?php
$arr = [
    'foo',
    'bar'=>'alfa',
    'baz'=>['a'=>'hello', 'b'=>'world'],
];

foreach($arr as $k=>$v) {
    $kk = is_numeric($k) ? $v : $k;
    $vv = is_numeric($k) ? null : $v;
    $arr2[$kk] = $vv;
}

print_r($arr2);

산출:

Array (
    [foo] => 
    [bar] => alfa
    [baz] => Array (
            [a] => hello
            [b] => world
        )
)

Array_Walk를 기반 으로이 기능을 사용할 수 있습니다.

function mapToIDs($array, $id_field_name = 'id')
{
    $result = [];
    array_walk($array, 
        function(&$value, $key) use (&$result, $id_field_name)
        {
            $result[$value[$id_field_name]] = $value;
        }
    );
    return $result;
}

$arr = [0 => ['id' => 'one', 'fruit' => 'apple'], 1 => ['id' => 'two', 'fruit' => 'banana']];
print_r($arr);
print_r(mapToIDs($arr));

그것은 :

Array(
    [0] => Array(
        [id] => one
        [fruit] => apple
    )
    [1] => Array(
        [id] => two
        [fruit] => banana
    )
)

Array(
    [one] => Array(
        [id] => one
        [fruit] => apple
    )
    [two] => Array(
        [id] => two
        [fruit] => banana
    )
)

흠, 전에는 테스트가 아니지만이 코드가 작동한다고 생각합니다.

function replace_array_key($data) {
    $mapping = [
        'old_key_1' => 'new_key_1',
        'old_key_2' => 'new_key_2',
    ];

    $data = json_encode($data);
    foreach ($mapping as $needed => $replace) {
        $data = str_replace('"'.$needed.'":', '"'.$replace.'":', $data);
    }

    return json_decode($data, true);
}

이해하기 간단한 보존 자 주문 :

function rename_array_key(array $array, $old_key, $new_key) {
  if (!array_key_exists($old_key, $array)) {
      return $array;
  }
  $new_array = [];
  foreach ($array as $key => $value) {
    $new_key = $old_key === $key
      ? $new_key
      : $key;
    $new_array[$new_key] = $value;
  }
  return $new_array;
}

가장 좋은 방법은 참조를 사용하고 UnSet을 사용하지 않는 것입니다 (메모리를 청소하기위한 또 다른 단계)

$tab = ['two' => [] ];

해결책:

$tab['newname'] = & $tab['two'];

당신은 하나의 원본과 하나의 참조가 새 이름을 가지고 있습니다.

또는 하나의 값으로 두 개의 이름을 갖고 싶지 않다면 좋은 탭이 좋다. 다른 탭을 만들고 참조 할 때.

foreach($tab as $key=> & $value) {
    if($key=='two') { 
        $newtab["newname"] = & $tab[$key];
     } else {
        $newtab[$key] = & $tab[$key];
     }
}

Iterration은 모든 어레이를 복제하는 것보다 키에서 더 좋습니다. 100 행 +++ 등과 같은 긴 데이터가있는 경우 이전 배열을 청소합니다.

주어진 배열의 키에 콜백을 적용하는 간단한 기능을 작성할 수 있습니다. 비슷하다 Array_map

<?php
function array_map_keys(callable $callback, array $array) {
    return array_merge([], ...array_map(
        function ($key, $value) use ($callback) { return [$callback($key) => $value]; },
        array_keys($array),
        $array
    ));
}

$array = ['a' => 1, 'b' => 'test', 'c' => ['x' => 1, 'y' => 2]];
$newArray = array_map_keys(function($key) { return 'new' . ucfirst($key); }, $array);

echo json_encode($array); // {"a":1,"b":"test","c":{"x":1,"y":2}}
echo json_encode($newArray); // {"newA":1,"newB":"test","newC":{"x":1,"y":2}}

여기에 요점이 있습니다 https://gist.github.com/vardius/650367e15abfb58bcd72ca47eff096ca#file-array_map_keys-php.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top