2015-03-19 60 views
1

我有一個散列%defines_3它看起來像這樣如何使用s /作爲散列中的鍵?

 'PIOMUX2_UART_3_TXD' => 'CONFIG_PIO31_6_SELECTOR', 
     'PIOMUX_UART_1_TXD' => 'CONFIG_PIO22_7_SELECTOR', 
     'PIOMUX_UART_11_TXD' => 'CONFIG_PIO0_4_SELECTOR', 
     'PIOMUX_UART_10_TXD' => 'CONFIG_PIO0_1_SELECTOR', 
     'PIOMUX2_UART_1_TXD' => 'CONFIG_PIO25_2_SELECTOR', 
     'PIOMUX_UART_3_TXD' => 'CONFIG_PIO32_6_SELECTOR', 

要改變一些地方從所有按鍵和我做了這樣的價值觀:

for (values %defines_3)  
{ 
s/CONFIG_/PIO_M_U_/g; 
s/_SELECTOR//g; 
} 

for (keys %defines_3) 
{ 
s/_TXD//g; 
} 

print Dumper \%defines_3; 

我收到此之後:

 'PIOMUX2_UART_3_TXD' => 'PIO_M_U_PIO31_6', 
     'PIOMUX_UART_1_TXD' => 'PIO_M_U_PIO22_7', 
     'PIOMUX_UART_11_TXD' => 'PIO_M_U_PIO0_4', 
     'PIOMUX_UART_10_TXD' => 'PIO_M_U_PIO0_1', 
     'PIOMUX2_UART_1_TXD' => 'PIO_M_U_PIO25_2', 
     'PIOMUX_UART_3_TXD' => 'PIO_M_U_PIO32_6', 

所以基本上我不能替代鍵,但值正在被替換我想通過使用s /的方式。如何更換密鑰?

+0

你被要求做然後再正確縮進Perl代碼,以便可讀。當你尋求免費的幫助時,它只是禮貌的,它會幫助你閱讀你自己的代碼並解決你自己的問題。 – Borodin 2015-03-19 10:40:07

+0

@Borodin對不起,我將在未來照顧。 – Grace90 2015-03-19 10:58:52

+1

詢問如何在散列的索引上使用s ///,例如詢問如何在數組的索引上使用s ///。沒有意義。刪除舊元素並使用新密鑰重新創建它。 – ikegami 2015-03-19 12:52:02

回答

4

values()正在生產lvalues這是因爲foreach別名到$_因此可以直接更改。 keys()必須從哈希才能被刪除,變更,

for (keys %defines_3) { 
    my $v = delete $defines_3{$_}; 
    s/_TXD//g; 
    $defines_3{$_} = $v; 
} 

或其中有/r交換機支持新的perl,

for (keys %defines_3) { 
    $defines_3{ s/_TXD//gr } = delete $defines_3{$_}; 
} 
+0

TMTOWTDI,'my @v = values%h; s/_TXD // g代表我的@k =鍵%h; %h =(); @h {@k} = @v;' – 2015-03-19 06:25:25

+0

非常感謝:)所以基本上我們必須將相應鍵的值存儲在其他地方,然後更改鍵並將值返回給..我對嗎?你做了什麼做%h =()? – Grace90 2015-03-19 06:45:58

+1

@ Grace90是的,你必須先刪除它們。 '%h =();'清空散列(分配空列表)。 – 2015-03-19 08:11:38

2

您不能重命名哈希鍵,因爲它們被存儲爲簡單的C字符串,而不是Perl標量變量。要達到相同的效果,您可以刪除哈希元素並使用新密鑰重新插入它。

有用地,delete運算符返回哈希元素的值,所以你可以這樣寫。

請注意,在迭代它時修改散列或數組通常是不明智的,但在這種情況下它是安全的,因爲keys %data表達式返回與所有散列鍵不同的散列鍵的固定列表哈希本身。

use strict; 
use warnings; 

my %data = (
    PIOMUX2_UART_3_TXD => 'CONFIG_PIO31_6_SELECTOR', 
    PIOMUX_UART_1_TXD => 'CONFIG_PIO22_7_SELECTOR', 
    PIOMUX_UART_11_TXD => 'CONFIG_PIO0_4_SELECTOR', 
    PIOMUX_UART_10_TXD => 'CONFIG_PIO0_1_SELECTOR', 
    PIOMUX2_UART_1_TXD => 'CONFIG_PIO25_2_SELECTOR', 
    PIOMUX_UART_3_TXD => 'CONFIG_PIO32_6_SELECTOR', 
); 

for my $key (keys %data) { 
    (my $new_key = $key)    =~ s/_TXD$//; 
    (my $new_val = delete $data{$key}) =~ s/^CONFIG_(.+)_SELECTOR$/PIO_M_U_$1/; 
    $data{$new_key} = $new_val; 
} 

use Data::Dump; 
dd \%data; 

輸出

{ 
    PIOMUX2_UART_1 => "PIO_M_U_PIO25_2", 
    PIOMUX2_UART_3 => "PIO_M_U_PIO31_6", 
    PIOMUX_UART_1 => "PIO_M_U_PIO22_7", 
    PIOMUX_UART_10 => "PIO_M_U_PIO0_1", 
    PIOMUX_UART_11 => "PIO_M_U_PIO0_4", 
    PIOMUX_UART_3 => "PIO_M_U_PIO32_6", 
} 
+0

謝謝你了! – Grace90 2015-03-19 11:32:50

2

這可能是通過使用pairmap功能從最簡單的List::Util。對於輸入列表中的每個鍵/值對,其塊將執行一次,並返回其返回的任何值列表,如常規的map。這可以很容易地建立一個新的哈希出一箇舊:

use 5.014; # for the s///r syntax 
use List::Util qw(pairmap); 

my %new_hash = pairmap { 
    ($a =~ s/_TXD$//r, $b =~ s/^CONFIG_(.+)_SELECTOR$/PIO_M_U_$1/r) 
} %old_hash; 

如果你之前5.14卡住沒有s///r語法,你可以用

use List::Util qw(pairmap); 

my %new_hash = pairmap { 
    my ($key, $val) = ($a, $b); 
    $key =~ s/_TXD$//; 
    $val =~ s/^CONFIG_(.+)_SELECTOR$/PIO_M_U_$1/; 
    ($key, $val) 
} %old_hash;