【问题标题】:Whay is the most elegant way to turn a hash inside out?将哈希从里到外翻的最优雅的方法是什么?
【发布时间】:2012-03-05 08:01:48
【问题描述】:

将哈希从里到外的最优雅的方法是什么?

我的意思是用值替换键,反之亦然(假设所有值都是 100% 唯一的)。

例如

开始

my %start = (1=>"a", 2=>"b", 3=>"c");

# ...

# PROFIT: 
my %finish = ("c" => 3, "b" => 2, "a" => 1);

我知道我可以用蛮力的方式做到这一点:

foreach my $key (keys %start) {
    my $value = $start{$key};
    $finish{ $value } = $key;
}

但这不可能是最优雅的方式!

【问题讨论】:

  • 您的蛮力方法无法正常工作。你需要遍历keys %start
  • “100% 唯一”是什么意思?你从事广告工作吗?可以“95% 独一无二”吗?你会告诉你的妻子,她是你“95% 独一无二的爱人”吗?
  • @cjm - 你是对的。我进行了编辑以修复代码,并通过将变量声明为在最小范围内的词法来添加一些清理(换句话说,在任何地方添加了my)。 Ike - 如果您不同意,请随时恢复编辑。
  • @KerrekSB - 我是软件开发人员。这意味着没有重复项,这意味着您不必担心从同一个值映射多个键(在这种情况下,您需要丢失一些键,或者将一组键添加为列表)。如果我的英语不完美,我很抱歉。
  • @Ike 我认为 Kerrek 指出它们要么是独一无二的,要么不是独一无二的,两者之间没有区别。

标签: perl hash


【解决方案1】:

reverse 可能是最惯用的方式之一:

my %finish = reverse %start;

这是可行的,因为 reverse 将 %start 哈希作为表单列表 (key1 value1 key2 value2...keyN valueN);然后反转列表(valueN keyN ... value1 key1)。将该列表分配给哈希变量,然后将其转换为哈希,奇数元素成为键,偶数元素成为值

或者您可以使用map(不太优雅但仍然惯用):

my %finish = map { ( $start{$_} => $_ ) } keys %start;

【讨论】:

  • @finish{value %start} = keys %start 保留现有对。
  • reverse %start 很聪明,但可能有点太聪明了。
  • @tchrist,另外,您在values 中省略了“s”。 (请参阅我的回答,在您发表评论前 1 秒发布。)
  • @Ike 我的版本将内容添加到现有哈希中。它为那些未重新分配键的对保留现有的键/值对。 reverse 版本只有在你想要一个全新的哈希时才有效。
  • @tchrist - 我见过的最直观的解释是“sygil 表示您正在检索的数据结构中的数据量($ 1 个元素,@ 表示元素列表,%代表整个哈希),而大括号样式代表你的数据结构(数组代表方形,哈希代表卷曲)。
【解决方案2】:
my %start = (1=>"a", 2=>"b", 3=>"c");

my %finish;
@finish{values %start} = keys %start;

【讨论】:

  • 上周我花了大约半个 [已审查] 小时来向 Perl 初级课程解释该解决方案。我决定从材料中删除它。他们只是无法理解散列片。他们陷入困境,@ 表示数组;他们不明白 { 表示哈希,而 @ 是无关紧要的。
  • 虚拟+1(尚不能投票)以获得巧妙的解决方案。我不是一个完整的初学者,所以与上述评论中的学生没有同样的问题:)
  • @ike - 你现在应该有足够的代表来进行非虚拟投票。并且 +1 来自我的一个很好的惯用表达
猜你喜欢
  • 2013-12-06
  • 2011-07-19
  • 2022-08-17
  • 1970-01-01
  • 2011-05-16
  • 1970-01-01
  • 2012-07-09
  • 2010-10-11
  • 1970-01-01
相关资源
最近更新 更多