【问题标题】:Convert hash reference to array reference将哈希引用转换为数组引用
【发布时间】:2018-10-19 09:56:23
【问题描述】:

我希望在 perl 中可以从哈希中获取数组 ref 或将 ref 哈希转换为 ref 数组!?

例如:

%trad = ('January','Jan','February','Feb');
$ref = \%trad;      # made a reference on hash
$ref2 = [%{$ref}];  # convert ref hash to ref array

我们可以用其他方式写:

$ref2 = [%{\%trad}];

但是这段代码是散列上的 ref 数组的错觉,因为构造 $ref = [...] 创建了对匿名数组的引用,该数组是通过 Perl 从散列中复制元素而创建的。

您可以通过尝试填充 $ref2 指向的数组来看到这一点,这对哈希没有影响!

有没有办法通过使用真正的 ref 数组,如 C 中的强制转换方法,直接在内存区域中直接对哈希进行操作!?

【问题讨论】:

  • 这听起来很像 XY 问题。你想在这里完成什么?
  • Notrhing 特别是 :-) 我们可以在很多地方看到哈希和数组几乎相似:-) 哈希是一个特殊的数组,具有特定的方法来操作其中的数据。通过为我节省内存,引用提供了以优雅的方式操作这些对象的机会。 XY问题是什么意思? :-)
  • 对于 XY 问题可以:en.wikipedia.org/wiki/XY_problem。我的目标是真正知道我们是否可以在哈希上获得真正的 ref 数组...
  • 不,它们在这个意义上并不相似——它们都是数据结构,但它们以不同的方式工作。您在谈论“真正的 ref 数组”这一事实意味着我认为您正在关注如何在 C 中做某事 - 而 perl 不是那样工作的。因此,为什么我要问您实际上想要完成什么How hashes really work
  • 哈希和数组是完全不同的数据结构。 C 风格的演员阵容完全没用。在 Perl 或 C 中。

标签: arrays perl hash casting reference


【解决方案1】:

您不能直接对哈希进行操作,因为 perl 不能那样工作。引用不是 C 意义上的指针。您不能直接访问内存。

哈希和数组在表面上可能看起来很相似 - 因为您可以在它们之间进行转换:

my @array = %hash; 
   %hash = @array; 

而且它“有效”。但这掩盖了在幕后,他们是不同的野兽。 @array 仍然是元素的有序列表。 %hash 仍然是一个非确定性的有序字典。这个工作的原因是因为在列表上下文中枚举 %hash 会返回成对的值。您可以使用成对值列表填充散列。

确实如此;

my %hash = ( 'January' => 'Jan',
             'February' => 'Feb');

真的在做什么。您正在为哈希提供一个列表,并且它正在用它做正确的事情 - 将“键”与“值”关联为配对值。 (=> 与逗号基本相同,但经常这样使用,因为它更清晰地显示了键值关联)。

这是how hashes work 上的一篇较早的文章 - 在此期间发生了一些变化,但原理相似 - 有桶,哈希键基于内部算法映射到桶中。

当您在列表上下文中枚举整个散列时 - 它每次都以有效的随机顺序返回键值对,因为这就是它在后台使用散列查找机制“工作”的方式。

但这意味着寻找“真正的数组引用”和“直接在哈希上操作”并没有真正的意义 - perl 不支持像在 C 中那样做,因为这不是语言作品。

如果您真的想知道幕后发生的事情 - perlguts 将为您提供很多细节。但这与perl中的编码过程几乎无关。

【讨论】:

    【解决方案2】:

    好的,现在对我来说更清楚了。感谢您花时间回答我的问题。

    实际上我的困惑是相信 Perl 引用就像 C 中的引用一样工作。

    我发现这篇文章 http://www.perlmonks.org/?node_id=504196 解释了这个技巧,但它并不精确这个新创建的引用绑定到匿名数组或哈希:-(

    很遗憾我们不能这样做,在某些情况下它可能有用。

    例如要获取哈希的大小(键/值的数量),我们可以这样写:

    $size_hash = ( $#{ [ %{\%hash} ] } +1 ) / 2;
    

    我使用来自哈希的引用,该引用被转换为数组引用,之后我们可以轻松获得该数组的大小并除以 2 得到结果。

    我知道,有很多方法可以达到相同的目标,但我发现这种方法更“优雅”,而且我相信记忆力不那么完美 :-( 实际上不是,因为它创建了一个带有哈希数据的匿名数组:-(

    【讨论】:

    • 过早的优化是万恶之源。另外:为什么需要获取哈希的大小? scalar keys %hash 应该可以很好地解决问题。
    • Re "实际上我的困惑是相信 Perl 引用就像 C 中的引用一样工作。",引用是一个指针,你不能用它来做指针运算。它们在其他方面是相同的。
    • Re "获取我们可以写入的散列的大小(键/值的数量)",my $size = keys(%hash); 是首选(O(1) 时间和空间O(N) 时间和空间)。
    • Re "很遗憾我们不能这样做,在某些情况下它可能有用。",永远没有用。数据结构完全不同,因此强制转换永远不会起作用。
    • 您可以这样做,以便共享数组和散列的 ,这样如果您更改一个,另一个也会更改。
    猜你喜欢
    • 2017-01-06
    • 2010-09-29
    • 2019-10-27
    • 2019-05-23
    • 2012-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-26
    相关资源
    最近更新 更多