다른 검색/매핑 배열에 따라 배열의 키를 바꿉니다.
이 폼에 연관 배열이 있습니다.key => value
여기서 key는 숫자 값이지만 순차적인 숫자 값은 아닙니다.아이디입니다.이것은 대부분의 경우 괜찮습니다만, 사람이 읽을 수 있는 어레이의 이름을 취득해, 값을 변경하지 않고 키에 사용하는 기능을 원합니다.
이 기능을 하는 기능은 보이지 않지만 오래된 키와 새 키(둘 다 가지고 있음)를 입력하고 어레이를 변환해야 한다고 생각합니다.이것을 효율적으로 하는 방법이 있을까요?
$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);
$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
];
*/
사용자가 읽을 수 있는 이름을 ID에 매핑하는 두 번째 연관 배열을 사용할 수 있습니다.그것은 또한 다대1의 관계를 제공할 것이다.그런 다음 다음과 같은 작업을 수행합니다.
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;
}
두 솔루션의 간단한 벤치마크 비교.
솔루션 1 복사 및 삭제(주문 손실은 발생하지만 훨씬 빠름) https://stackoverflow.com/a/240676/1617857
<?php
$array = ['test' => 'value', ['etc...']];
$array['test2'] = $array['test'];
unset($array['test']);
솔루션 2 키 이름 변경 https://stackoverflow.com/a/21299719/1617857
<?php
$array = ['test' => 'value', ['etc...']];
$keys = array_keys( $array );
$keys[array_search('test', $keys, true)] = 'test2';
array_combine( $keys, $array );
벤치마크:
<?php
$array = ['test' => 'value', ['etc...']];
for ($i =0; $i < 100000000; $i++){
// Solution 1
}
for ($i =0; $i < 100000000; $i++){
// Solution 2
}
결과:
php solution1.php 6.33s user 0.02s system 99% cpu 6.356 total
php solution1.php 6.37s user 0.01s system 99% cpu 6.390 total
php solution2.php 12.14s user 0.01s system 99% cpu 12.164 total
php solution2.php 12.57s user 0.03s system 99% cpu 12.612 total
배열이 재귀적인 경우 다음 함수를 사용할 수 있습니다. 이 데이터를 테스트합니다.
$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;
}
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의 답변에 근거한 pretty.
사용방법:
_rename_arr_key('oldkey', 'newkey', $my_array);
이름을 바꾸면 true가 반환되고 그렇지 않으면 false가 반환됩니다.
이 코드는 이전 키를 새 키로 변경하는 데 도움이 됩니다.
$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");
간단한 작업:
이 함수는 타겟 $targets를 받아들이며 $replacements는 newkey=> oldkey 관련성을 포함하는 해시이기도 합니다.
이 함수는 원래의 순서를 유지합니다만, 퍼포먼스와 메모리에 관해서 매우 큰(10,000 이상의 레코드 등) 어레이에서는 문제가 발생할 가능성이 있습니다.
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;
}
질문 본문에 최소한의 검증 가능한 예가 없기 때문에 이 페이지에는 요구 사항에 대한 광범위한 해석이 포함되어 있습니다.일부 답변은 질문 요건을 이해하려고 애쓰지 않고 "제목"을 풀려고 하는 것일 뿐입니다.
키는 실제 ID 번호이고 값은 카운트입니다.이것은 대부분의 경우 괜찮습니다만, 사람이 읽을 수 있는 어레이의 이름을 취득해, 값을 변경하지 않고 키에 사용하는 기능을 원합니다.
PHP 키는 변경할 수 없지만 대체할 수 있습니다.이 때문에, 많은 회답이, 다음과 같은 기능을 사용하는 것을 추천합니다.array_search()
으로 성적이 와 (상대적으로 성적이 나쁘다)unset()
.
최종적으로 원래 카운트와 관련된 키로 이름을 사용하여 새 배열을 생성하려고 합니다.키 검색은 항상 값 검색보다 성능이 뛰어나기 때문에 이 작업은 검색 배열을 통해 가장 효율적으로 수행됩니다.
코드: (데모)
$idCounts = [
3 => 15,
7 => 12,
8 => 10,
9 => 4
];
$idNames = [
1 => 'Steve',
2 => 'Georgia',
3 => 'Elon',
4 => 'Fiona',
5 => 'Tim',
6 => 'Petra',
7 => 'Quentin',
8 => 'Raymond',
9 => 'Barb'
];
$result = [];
foreach ($idCounts as $id => $count) {
if (isset($idNames[$id])) {
$result[$idNames[$id]] = $count;
}
}
var_export($result);
출력:
array (
'Elon' => 15,
'Quentin' => 12,
'Raymond' => 10,
'Barb' => 4,
)
은 원래의 순서중요한 를, 이 합니다.isset()
.
여러 키를 동시에 교환하는 경우(주문 유지):
/**
* 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
)
)
이 기본 기능에서는 어레이 키를 스왑하고 어레이를 원래 순서로 유지합니다.
public function keySwap(array $resource, array $keys)
{
$newResource = [];
foreach($resource as $k => $r){
if(array_key_exists($k,$keys)){
$newResource[$keys[$k]] = $r;
}else{
$newResource[$k] = $r;
}
}
return $newResource;
}
그런 다음 모든 'a' 키를 루프 통과하여 'z'와 바꿀 수 있습니다. 예를 들어...
$inputs = [
0 => ['a'=>'1','b'=>'2'],
1 => ['a'=>'3','b'=>'4']
]
$keySwap = ['a'=>'z'];
foreach($inputs as $k=>$i){
$inputs[$k] = $this->keySwap($i,$keySwap);
}
이 함수는 인덱스 검색과 결합하여 배열 키의 이름을 그대로 변경합니다.
function renameArrKey($arr, $oldKey, $newKey){
if(!isset($arr[$oldKey])) return $arr; // Failsafe
$keys = array_keys($arr);
$keys[array_search($oldKey, $keys)] = $newKey;
$newArr = array_combine($keys, $arr);
return $newArr;
}
사용방법:
$arr = renameArrKey($arr, 'old_key', 'new_key');
첫 번째 키의 이름을 바꾸면 다음과 같이 됩니다.
$a = ['catine' => 'cat', 'canine' => 'dog'];
$tmpa['feline'] = $a['catine'];
unset($a['catine']);
$a = $tmpa + $a;
다음으로 print_raa)는 복구된 어레이를 순서대로 렌더링합니다.
Array
(
[feline] => cat
[canine] => dog
)
이것은, 임의의 키의 이름을 변경하는 경우에 유효합니다.
$a = ['canine' => 'dog', 'catine' => 'cat', 'porcine' => 'pig']
$af = array_flip($a)
$af['cat'] = 'feline';
$a = array_flip($af)
print_r4a)
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);
}
가장 좋은 방법은 참조를 사용하는 것이지 설정되지 않은 것을 사용하지 않는 것입니다(메모리를 정리하는 다른 단계가 됩니다).
$tab = ['two' => [] ];
솔루션:
$tab['newname'] = & $tab['two'];
원본과 새 이름의 참조가 각각 하나씩 있습니다.
또는 하나의 값에 두 개의 이름을 붙이지 않으려면 다른 탭을 만들고 참조를 위해 앞지르는 것이 좋습니다.
foreach($tab as $key=> & $value) {
if($key=='two') {
$newtab["newname"] = & $tab[$key];
} else {
$newtab[$key] = & $tab[$key];
}
}
모든 어레이를 클론하는 것보다 키를 반복하는 것이 좋습니다.또, 100 행 + + + 등의 긴 데이터가 있는 경우는, 낡은 어레이를 클리닝 하는 것이 좋습니다.
주문 내용을 알기 쉽게 정리할 수 있습니다.
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;
}
지정된 배열의 키에 콜백을 적용하는 간단한 함수를 쓸 수 있습니다.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 입니다.
여기 실험(테스트)이 있습니다.
초기 어레이(0,1,2와 같은 키)
$some_array[] = '6110';//
$some_array[] = '6111';//
$some_array[] = '6210';//
키 이름을 다음과 같이 변경해야 합니다.human_readable15
,human_readable16
,human_readable17
이미 올린 거랑 비슷한 거.루프할 때마다 필요한 키 이름을 설정하고 초기 배열에서 해당 키를 제거합니다.
예를 들어 mysql에 삽입했습니다.$some_array
얻었다lastInsertId
그리고 그리고 그게 jquery한 키-값 하나 보내 줄 필요가 있다.
$first_id_of_inserted = 7;//lastInsertId
$last_loop_for_some_array = count($some_array);
for ($current_loop = 0; $current_loop < $last_loop_for_some_array ; $current_loop++) {
$some_array['human_readable'.($first_id_of_inserted + $current_loop)] = $some_array[$current_loop];//add new key for intial array
unset( $some_array[$current_loop] );//remove already renamed key from array
}
그리고 이것은 이름이 변경된 키를 가진 새로운 어레이입니다.
echo '<pre>', print_r($some_array, true), '</pre>$some_array in '. basename(__FILE__, '.php'). '.php <br/>';
만약 대신human_readable15
,human_readable16
,human_readable17
필요성이 다른.그런데 이런 일을 만들 수 있습니다.
$arr_with_key_names[] = 'human_readable';
$arr_with_key_names[] = 'something_another';
$arr_with_key_names[] = 'and_something_else';
for ($current_loop = 0; $current_loop < $last_loop_for_some_array ; $current_loop++) {
$some_array[$arr_with_key_names[$current_loop]] = $some_array[$current_loop];//add new key for intial array
unset( $some_array[$current_loop] );//remove already renamed key from array
}
음, 전에 테스트를 해본 적은 없지만 이 코드가 작동되는 것 같아
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);
}
언급URL : https://stackoverflow.com/questions/240660/replace-keys-in-an-array-based-on-another-lookup-mapping-array
'sourcecode' 카테고리의 다른 글
MySQL 최적화: Different가 너무 느리다 (0) | 2022.09.06 |
---|---|
클래스를 보호 클래스로 정의할 수 없는 이유는 무엇입니까? (0) | 2022.09.06 |
AJAX 요청은 PHP 세션 정보를 유지합니까? (0) | 2022.09.06 |
Django 서버 오류: 포트가 이미 사용 중입니다. (0) | 2022.09.05 |
어떻게 하면 WAMP에서 마리아db를 제대로 제거할 수 있을까? (0) | 2022.09.05 |