Perl,将数字键哈希转换为数组

     2023-03-24     205

关键词:

【中文标题】Perl,将数字键哈希转换为数组【英文标题】:Perl, convert numerically-keyed hash to array 【发布时间】:2011-02-23 20:04:45 【问题描述】:

如果我在 Perl 中有一个包含完整和连续整数映射的哈希(即,从 0 到 n 的所有键都映射到某个东西,除此之外没有键),有没有办法将它转换为数组?

我知道我可以遍历键/值对并将它们放入一个新数组中,但有些东西告诉我应该有一个内置的方法来做到这一点。

【问题讨论】:

咆哮警告! 为什么每个人都想对键进行排序?没有必要,它使算法慢得多!排序很慢! runrig 的答案是这里最好的答案。如果散列稀疏,它将起作用。数组保持顺序,但它们是随机访问结构。伙计们,我们不使用链接列表! 你是对的:有一种内置的方法。请参阅Ether's answer。 :) 这个问题是列表上下文和数组之间存在差异的另一个原因。再加上切片,它可以让你在列表和哈希之间进行转换,而无需任何特殊的魔法或迭代,而恕我直言是 Perl 最强大的特性之一。 【参考方案1】:

如果您的原始数据源是哈希:

# first find the max key value, if you don't already know it:
use List::Util 'max';
my $maxkey = max keys %hash;

# get all the values, in order
my @array = @hash0 .. $maxkey;

或者,如果您的原始数据源是 hashref:

my $maxkey = max keys %$hashref;
my @array = @$hashref0 .. $maxkey;

使用这个例子很容易测试:

my %hash;
@hash0 .. 9 = ('a' .. 'j');

# insert code from above, and then print the result...
use Data::Dumper;
print Dumper(\%hash);
print Dumper(\@array);

$VAR1 = 
          '6' => 'g',
          '3' => 'd',
          '7' => 'h',
          '9' => 'j',
          '2' => 'c',
          '8' => 'i',
          '1' => 'b',
          '4' => 'e',
          '0' => 'a',
          '5' => 'f'
        ;
$VAR1 = [
          'a',
          'b',
          'c',
          'd',
          'e',
          'f',
          'g',
          'h',
          'i',
          'j'
        ];

【讨论】:

hashref 没有-> 运算符? @Zaid:不,这不是你在 hashrefs 中使用切片的方式。 愚蠢的我,它被转换为一个数组,这就是为什么不需要箭头运算符的原因。 不涉及强制转换或数组。 hash slice 返回一个list 即使哈希键不是数字,这也能工作?【参考方案2】:

您可以使用 values 函数从哈希中提取所有值:

my @vals = values %hash;

如果您希望它们按特定顺序排列,则可以按所需顺序放置键,然后从中获取hash slice

my @sorted_vals = @hashsort  $a <=> $b  keys %hash;

【讨论】:

【参考方案3】:

好的,这不是很“内置”但可以工作。恕我直言,它比任何涉及“排序”的解决方案更受欢迎,因为它更快。

map  $array[$_] = $hash$_  keys %hash; # Or use foreach instead of map

否则效率会降低:

my @array = map  $hash$_  sort  $a<=>$b  keys %hash;

【讨论】:

或避免在 void 上下文中映射:$array[$_] = $hash$_ for keys %hash; 那必须是sort $a &lt;=&gt; $b 。请记住,sort 默认为字符串比较。【参考方案4】:

Perl 没有提供内置的方法来解决您的问题。

如果您知道密钥覆盖特定范围 0..N,您可以利用这一事实:

my $n = keys(%hash) - 1;
my @keys_and_values = map  $_ => $hash$_  0 .. $n;
my @just_values     = @hash0 .. $n;

【讨论】:

或者my $n = $#[keys %hash],如果你讨厌常量减法...【参考方案5】:

这将使未在%hashed_keys 中定义的键保留为undef

# if we're being nitpicky about when and how much memory
# is allocated for the array (for run-time optimization):
my @keys_arr = (undef) x scalar %hashed_keys;

@keys_arr[(keys %hashed_keys)] =
    @hashed_keys(keys %hashed_keys);

而且,如果您使用参考:

@$keys_arr[(keys %$hashed_keys)] = 
    @$hashed_keys(keys %$hashed_keys);

或者,更危险的是,因为它假设你说的是真的(它可能并不总是真的......只是说!):

@keys_arr = @hashed_keys(sort $a <=> $b keys %hashed_keys);

但这有点离题了。如果它们一开始是整数索引的,为什么现在它们在散列中?

【讨论】:

善用切片。关于数据结构的初始选择也很好。太糟糕了,你提出了sort,排序很慢(见我上面的咆哮)并且容易出错并且不可取。 @daotoad - 第一个(也是推荐的)解决方案不使用sort。但是,我完全同意sort;它每次调用最多生成 n 平方任意函数调用 [提示:这很糟糕]。【参考方案6】:

正如 DVK 所说,没有内置的方法,但这可以解决问题:

my @array = map $hash$_ sort $a <=> $b keys %hash;

或者这个:

my @array;

keys %hash;

while (my ($k, $v) = each %hash) 
    $array[$k] = $v

基准测试看看哪个更快,我猜是第二个。

【讨论】:

嗯,第一个平均为 O(NlogN),但最高为 O(N^2)。第二种方法只是 O(N)。无需基准测试。【参考方案7】:
@a = @hsort  $a <=> $b  keys %h;

【讨论】:

【参考方案8】:

结合FM 和Ether 的答案可以避免定义一个原本不必要的标量:

my @array = @hash 0 .. $#[ keys %hash ] ;

巧妙的是,与 scalar 方法不同的是,$# 即使在第一个元素的默认索引 $[ 不为零的情况下也能正常工作。

当然,这意味着写一些愚蠢和混淆的东西:

my @array = @hash $[ .. $#[ keys %hash ] ;   # Not recommended

但是总有远程机会有人在某处需要它(wince)...

【讨论】:

【参考方案9】:
$Hash_value = 

'54' => 'abc',
'55' => 'def',
'56' => 'test',
;
while (my ($key,$value) = each %$Hash_value)

 print "\n $key > $value";

【讨论】:

【参考方案10】:

我们可以写一段如下:

$j =0;
while(($a1,$b1)=each(%hash1))
    $arr[$j][0] = $a1;
    ($arr[$j][1],$arr[$j][2],$arr[$j][3],$arr[$j][4],$arr[$j][5],$arr[$j][6]) = values($b1);
    $j++;

$a1 包含密钥和 $b1 包含值 在上面的示例中,我有数组的哈希,并且该数组包含 6 个元素。

【讨论】:

如果原始哈希包含 100 个元素怎么办?或者如果你不知道它包含多少元素?【参考方案11】:

一个简单的方法是@array = %hash

例如,

my %hash = (
    "0"  => "zero",
    "1" => "one",
    "2"  => "two",
    "3"  => "three",
    "4"  => "four",
    "5"  => "five",
    "6"  => "six",
    "7"  => "seven",
    "8"  => "eight",
    "9"  => "nine",
    "10"  => "ten",
);

my @array = %hash;

print "@array"; 会产生以下输出,

3 三 9 九 5 五 8 八 2 二 4 四 1 一 10 十 7 七 0 零 六六

【讨论】:

将 XML 转换为 Perl 哈希

】将XML转换为Perl哈希【英文标题】:ConvertXMLtoPerlHash【发布时间】:2021-07-1308:33:30【问题描述】:对于下面的XML结构,我正在尝试获取一个对应的PerlHash数组<root><refname="abc_sia_%version1.ref%"><funcenvname="test01"objectdir="/home/p... 查看详情

将数组值转换为哈希键

Usefulforspeedingupsearches.#aisthearraywewanttoturnintoahashHash[*a.zip([true]*a.size).flatten] #Example:people=%w[JohnMaryPaul]query_people=Hash[*people.zip([true]*people.size).flatten] query_people["John"]#returns... 查看详情

哈希表

...存的就是对应的值。这样就可以快速地访问任意键的值,哈希表是这种简易方法的拓展并能够处理更加复杂类型的键。哈希表需要用算术操作将键转换为数组的索引来访问数组中的键值对。 哈希表的查找算法主要分为两步:... 查看详情

在 perl 中使用 TEXT::CSV_XS 模块将 CSV 文件转换为哈希结构

】在perl中使用TEXT::CSV_XS模块将CSV文件转换为哈希结构【英文标题】:ToConvertCSVFiletoHashStructureusingTEXT::CSV_XSModuleinperl【发布时间】:2020-09-2110:40:50【问题描述】:下面的代码用于读取csv文件并转换为哈希。键取决于用户需要的键... 查看详情

如何将两个数组分配给 Perl 中的哈希?

】如何将两个数组分配给Perl中的哈希?【英文标题】:HowcanIassigntwoarraystoahashinPerl?【发布时间】:2011-04-1213:43:09【问题描述】:我有两个大数组的代码行(所以不能只将其写入哈希),我想用哈希连接它们。例如,$array1[0]成为... 查看详情

如何替换 Perl 哈希键?

】如何替换Perl哈希键?【英文标题】:HowcanIreplaceaPerlhashkey?【发布时间】:2010-12-0204:47:03【问题描述】:假设我有这样的哈希:$data=\'key1\'=>\'key2\'=>\'value1\',\'key3\'=>\'key4\'=>\'key5\'=>\'value2\',;现在,我如何将键“key5”替... 查看详情

如何将哈希映射键转换为列表?

】如何将哈希映射键转换为列表?【英文标题】:Howtoconverthashmapkeysintolist?【发布时间】:2015-10-2711:50:58【问题描述】:我有一个哈希映射,我正在尝试将键转换为列表。代码如下:List<ARecord>recs=newArrayList<ARecord>();HashMap... 查看详情

在 Perl 中使用 XML::Simple 将哈希转换为 XML 后内容丢失

】在Perl中使用XML::Simple将哈希转换为XML后内容丢失【英文标题】:ContentmissingafterconvertinghashtoXMLusingXML::SimpleinPerl【发布时间】:2021-08-1312:35:17【问题描述】:代码:my$test=\'a\'=>\'disabled\'=>\'false\',\'options\'=>\'%build_options\',\'ma 查看详情

在 Clojure 中将元组数组转换为哈希映射

】在Clojure中将元组数组转换为哈希映射【英文标题】:Convertanarrayoftuplesintoahash-mapinClojure【发布时间】:2011-05-1817:47:04【问题描述】:我有一个元组数组,其中每个元组是一个2元组,带有一个键和一个值。将这个元组数组转换... 查看详情

如何对 Perl 哈希值进行排序并相应地对键进行排序(可能在两个数组中)?

】如何对Perl哈希值进行排序并相应地对键进行排序(可能在两个数组中)?【英文标题】:HowcanIsortaPerlhashonvaluesandorderthekeyscorrespondingly(intwoarraysmaybe)?【发布时间】:2012-06-0916:38:56【问题描述】:在Perl中,我想按数值对哈希的... 查看详情

将哈希表转换为 OCaml 中的对列表(键、值)

】将哈希表转换为OCaml中的对列表(键、值)【英文标题】:Convertinghashtabletolistofpairs(key,value)inOCaml【发布时间】:2011-05-0221:04:56【问题描述】:有没有办法将哈希表转换为OCaml中的(键、对)值列表?我知道,给定一个哈希表ht... 查看详情

在Ruby中将嵌套哈希键从CamelCase转换为snake_case

】在Ruby中将嵌套哈希键从CamelCase转换为snake_case【英文标题】:ConvertingnestedhashkeysfromCamelCasetosnake_caseinRuby【发布时间】:2012-02-0104:15:51【问题描述】:我正在尝试构建一个API包装器gem,但在将哈希键从API返回的JSON转换为更Rubyish... 查看详情

hash在perl中的用法(转载)

...lue)关联成为可能。虽然这些哈希要远远比普通系统中以数字索引的数组用途更广,但是往往也会使初学者不知所措。这就是要写本篇文章的原因所在??它将告诉你如何创建Perl的哈希,如何插入、删除要素,以及如何创建嵌套哈... 查看详情

Perl:将数组分配给哈希

】Perl:将数组分配给哈希【英文标题】:Perl:Assigninganarraytoahash【发布时间】:2011-07-2001:56:55【问题描述】:此语法有效:$b"x"=[1,2,3];pp%b;#Displays("x",[1,2,3])但我需要能够动态创建数组的内容并在以后分配它。这不起作用;帮助,... 查看详情

Perl - 将数字转换为 2 个十进制

】Perl-将数字转换为2个十进制【英文标题】:Perl-ConvertNumberto2Decimal【发布时间】:2018-03-2117:43:19【问题描述】:我想将数字转换为小数。我一直在使用:sprintf("%02d",$price/12);只有有时候$price是一个整数,所以我得到的是06而不是6... 查看详情

如何将哈希值转换为数组

】如何将哈希值转换为数组【英文标题】:Howtoconvertvaluesofhashintoarray【发布时间】:2021-11-0111:05:10【问题描述】:我必须将弹性搜索结果解析为特定格式。为此,我需要将搜索结果哈希值放入数组我有这个:hash="ABC":"attributes":"id... 查看详情

在 Perl 中按顺序打印哈希键

】在Perl中按顺序打印哈希键【英文标题】:PrinthashkeyssequentiallyinPerl【发布时间】:2022-01-1916:41:36【问题描述】:我有哈希数组,需要迭代并打印序列中的值-id,name,mailid。但是当我打印键的内容时,它一直在洗牌。如何打印如下... 查看详情

将哈希表的键转换为字符串列表

】将哈希表的键转换为字符串列表【英文标题】:Convertahashtable\'skeystoalistofstrings【发布时间】:2012-12-1220:11:27【问题描述】:我想做[string]::Join(",",$HashTable.Keys);,但返回System.Collections.Hashtable+KeyCollection...而不是枚举值。... 查看详情