PHP में, आप ऐरे एलिमेंट की कुंजी कैसे बदलते हैं?


348

मेरे पास फॉर्म में एक साहचर्य सरणी है key => valueजहां कुंजी एक संख्यात्मक मान है, हालांकि यह अनुक्रमिक संख्यात्मक मान नहीं है। कुंजी वास्तव में एक आईडी नंबर है और मूल्य एक गिनती है। यह अधिकांश उदाहरणों के लिए ठीक है, हालांकि मैं एक ऐसा फ़ंक्शन चाहता हूं जो कि सरणी के मानव-पठनीय नाम प्राप्त करता है और कुंजी के लिए उपयोग करता है, बिना मूल्य को बदले।

मुझे ऐसा कोई फ़ंक्शन दिखाई नहीं दिया जो ऐसा करता हो, लेकिन मैं मान रहा हूं कि मुझे पुरानी कुंजी और नई कुंजी (मेरे पास दोनों हैं) प्रदान करने और सरणी को बदलने की आवश्यकता है। क्या ऐसा करने का एक कुशल तरीका है?


जवाबों:


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

5
बस सावधान रहें कि 1) कोई भी दो कुंजियाँ एक ही मानव-पठनीय संस्करण 2 नहीं हैं) कोई मानव-पठनीय संस्करण संख्याएँ नहीं होती हैं
ग्रेग

81
इसके अलावा यह निश्चित रूप से सरणी के क्रम को बदल देगा, जिससे आपको सावधान रहने की आवश्यकता हो सकती है। यहां तक ​​कि PHP में साहचर्य सरणियों का आदेश दिया जाता है, और कभी-कभी उस आदेश का लाभ उठाया जाता है।
रॉबिन विंसलो

7
हाँ, महान बिंदु रॉबिन। क्या एक ही क्रम रखने का एक तरीका है? या क्या आपको इसे प्राप्त करने के लिए एक नई सरणी बनाने की आवश्यकता है?
साइमन ईस्ट

40
बोनस प्रश्न: आईडी कैसे बदलें, लेकिन सरणी ऑर्डर को संरक्षित करें?
पेट्र पेलर

17
यदि कुंजी मान नहीं बदल रहा है, तो आप एक सरणी तत्व को हटा देंगे। आप इसके लिए जाँच कर सकते हैं।
पीच

97

जिस तरह से आप ऐसा करते हैं और सरणी के क्रम को संरक्षित करते हैं, सरणी कुंजियों को एक अलग सरणी में रखकर, उस सरणी में कुंजी को ढूंढें और प्रतिस्थापित करें और फिर इसे मानों के साथ संयोजित करें।

यहाँ एक फ़ंक्शन है जो बस ऐसा करता है:

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 );
}

2
धन्यवाद यह वास्तव में सहायक था क्योंकि मुझे सरणी के क्रम को संरक्षित करने की आवश्यकता थी। इस पृष्ठ को खोजने से पहले मैंने पहले ही स्वीकृत उत्तर का प्रयास कर लिया था।
जिलियटेक

3
हां, सरणी के क्रम को संरक्षित करना ज्यादा पसंद करता है, देखने में भद्दा लगता है।
फिल कुक

2
प्रमुख आदेश को संरक्षित करना था, अच्छा है, एक आकर्षण की तरह काम किया!
लर्नर

यदि आप प्रदर्शन चाहते हैं या संरक्षण चाहते हैं तो दिमाग लगाएं: stackoverflow.com/a/58619985/1617857
Léo Benoist

54

यदि आपका arrayडेटाबेस क्वेरी से बनाया गया है, तो आप mysqlकथन से सीधे कुंजी बदल सकते हैं :

के बजाय

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

कुछ का उपयोग करें:

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

महान जवाब, बहुत मूल्यवान!
देवमटार्डे

20

कर्नेलम का उत्तर अच्छा है, लेकिन टिप्पणी (परस्पर विरोधी कुंजियों) में ग्रेग द्वारा उठाए गए मुद्दे से बचने के लिए, एक नए सरणी का उपयोग करना अधिक सुरक्षित होगा

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

यह एक अच्छा समाधान है, इसलिए जब तक आपका सरणी एक उचित आकार का हो। यदि आपका सरणी उपलब्ध PHP मेमोरी के आधे से अधिक का उपभोग करता है, तो यह काम नहीं करेगा।
किंगजेफ्रे

12
@kingjeffrey, वास्तव में नहीं। सरणी मानों को तब तक डुप्लिकेट नहीं किया जाएगा, जब तक वे संशोधित किए बिना "बस कॉपी किए गए" न हों। उदाहरण के लिए, यदि एक ऐसा सरणी है जिसमें 10'000 तत्व हैं और 40MB मेमोरी का उपभोग करते हैं, तो इसकी प्रतिलिपि बनाने से उस मेमोरी की खपत होगी जो कि 10'000 स्टोर करने के लिए आवश्यक है, केवल मानों की प्रतियों के बजाय पहले से मौजूद मानों के संदर्भ में , इसलिए यदि 1 सरणी 40MB का उपभोग करती है, तो इसकी प्रतिलिपि शायद 0.5MB (परीक्षण) का उपभोग कर सकता है।
बाइनरीएलवी

17

आप एक दूसरे साहचर्य सरणी का उपयोग कर सकते हैं जो आईडी के लिए मानव पठनीय नामों को मैप करता है। यह भी एक से कई संबंध प्रदान करेगा। फिर कुछ इस तरह से करें:

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

11

यदि आप यह भी चाहते हैं कि नई सरणी कुंजी की स्थिति वही हो जो आप इसे कर सकते हैं:

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;
}

7

यदि आपका सरणी पुनरावर्ती है तो आप इस फ़ंक्शन का उपयोग कर सकते हैं: इस डेटा का परीक्षण करें:

    $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;   
}

7
$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
];
*/

3
मैं अपने सरणी कार्यों से मुझे प्यार करता हूं। मैं सभी कुंजियों का नाम बदलने और सरणी क्रम बनाए रखने के लिए एक अच्छा वन-लाइनर के रूप में यह सुझाव देने वाला था, लेकिन मैं आपको इसके बजाय सलाह दूंगा।
शरद ऋतु लियोनार्ड

6

मुझे कर्नेलम का समाधान पसंद है, लेकिन मुझे कुछ ऐसी चीज़ों की ज़रूरत थी जो संभावित प्रमुख संघर्षों को संभालती हो (जहाँ एक नई कुंजी मौजूदा कुंजी से मेल खा सकती है)। यहां वह है जो मैंने जुटाया:

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

6

यहाँ एक सहायक समारोह है जिसे प्राप्त करने के लिए:

/**
 * 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;
    }
}

@ कर्नेलम उत्तर के आधार पर सुंदर ।

उपयोग:

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

यह सफल नाम पर सच लौटेगा , अन्यथा गलत


ज्ञात हो कि यह सरणी के क्रम को बदल देता है (बदला हुआ कुंजी का तत्व सरणी के अंत में होगा, सरणी में उसी स्थिति में नहीं है जितना मूल रूप से था)। इसके अलावा, मैं आमतौर पर एक अंडरस्कोर के साथ एक फ़ंक्शन नाम शुरू नहीं करूंगा (जो परंपरागत रूप से विशेष आंतरिक उपयोग कार्यों को नामित करने के लिए उपयोग किया जाता है)।
1

4

आसान सामान:

यह फ़ंक्शन $ हैश को लक्ष्य स्वीकार करेगा और $ रिप्लेसमेंट भी एक हैश है जिसमें newkey => oldkey संघ शामिल हैं

यह फ़ंक्शन मूल आदेश को संरक्षित करेगा , लेकिन प्रदर्शन और मेमोरी के संबंध में बहुत बड़े (जैसे 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;       
}

4

यह कोड पुराने को नए में बदलने में मदद करेगा

$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");

3

दोनों समाधान की सरल बेंचमार्क तुलना।

समाधान 1 कॉपी और निकालें (ऑर्डर खो दिया) https://stackoverflow.com/a/240676/1617857

for ($i =0; $i < 100000000; $i++){
    $array = ['test' => 'value'];
    $array['test2'] = $array['test'];
    unset($array['test']);
}

समाधान 2 कुंजी का नाम बदलें https://stackoverflow.com/a/21299719/1617857

for ($i =0; $i < 100000000; $i++){
    $array = ['test' => 'value'];
    $keys = array_keys( $array );
    $keys[array_search('test', $keys, true)] = 'test2';
    array_combine( $keys, $array );
}

परिणाम:

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

2

आप इस फ़ंक्शन का उपयोग 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
    )
)

1

यह पहली कुंजी का नाम बदलने के लिए काम करता है:

$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 ($ क)

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);
}

1

यदि आप एक साथ कई कुंजियों को बदलना चाहते हैं (ऑर्डर को संरक्षित करना):

/**
 * 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);

1

एक सरणी तत्व की कुंजी को बदलने का एक वैकल्पिक तरीका है जब पूर्ण सरणी के साथ काम कर रहा है - सरणी के क्रम को बदले बिना। यह बस सरणी को एक नए सरणी में कॉपी करना है।

उदाहरण के लिए, मैं एक मिश्रित, बहुआयामी सरणी के साथ काम कर रहा था जिसमें अनुक्रमित और साहचर्य कुंजी शामिल थी - और मैं ऑर्डर को तोड़ने के बिना पूर्णांक कुंजियों को उनके मूल्यों से बदलना चाहता था।

मैंने सभी सांख्यिक सरणी प्रविष्टियों के लिए कुंजी / मान स्विच करके ऐसा किया है - यहाँ: ['0' => 'फू']। ध्यान दें कि आदेश बरकरार है।

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

1

सबसे अच्छा तरीका संदर्भ का उपयोग कर रहा है, और न कि परेशान का उपयोग करना (जो स्मृति को साफ करने के लिए एक और कदम बनाते हैं)

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

समाधान:

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

आपके पास नए नाम के साथ एक मूल और एक संदर्भ है।

या यदि आप नहीं चाहते कि एक मूल्य में दो नाम हों तो अच्छा है कि एक और टैब बनाएं और संदर्भ के लिए फॉरचेट करें

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

यदि आप 100 पंक्तियों +++ आदि की तरह लंबा डेटा रखते हैं, तो क्लोनिंग सभी सरणी से कुंजी पर बेहतर है, और पुराने सरणी को साफ करना।


0

हम्म, मैं पहले परीक्षण नहीं कर रहा हूं, लेकिन मुझे लगता है कि यह कोड काम कर रहा है

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);
}

Json सांकेतिक शब्दों में बदलना और डिकोड? यह वास्तव में बुरा जवाब है।
किक्सॉर्ज़

0

जो एक संरक्षक के आदेश को समझने के लिए सरल है:

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;
}

0

आप साधारण फ़ंक्शन लिख सकते हैं जो दिए गए एरे की कुंजियों पर कॉलबैक लागू करता है। 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}}

यहाँ एक gist https://gist.github.com/vardius/650367e15abfb58bcd72ca47eff096ca#file-array_map_keys-php है


0

यह फ़ंक्शन इंडेक्स खोज के साथ संयोजन करके, अपनी स्थिति बनाए रखते हुए, एक सरणी कुंजी का नाम बदलेगा।

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');

-1

यह मूल कार्य सरणी कुंजियों की अदला-बदली करता है और सरणी को मूल क्रम में रखता है ...

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;
}

आप तब के माध्यम से लूप कर सकते हैं और सभी को स्वैप कर सकते हैं 'उदाहरण के लिए' 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);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.