【问题标题】:Any good collection module in perl?perl中有什么好的收集模块吗?
【发布时间】:2010-09-12 21:14:42
【问题描述】:

有人可以推荐一个 perl 中可以用来存储对象集合的好模块吗?

或者 ARRAY 是否足以满足大多数需求?

更新: 我正在寻找一个集合类,因为我希望能够执行诸如计算每个元素的集合级别属性之类的操作。

由于我需要执行许多这样的操作,我不妨编写一个可以由单个对象扩展的类。这个类显然适用于数组(或者可能是哈希)。

【问题讨论】:

    标签: perl collections


    【解决方案1】:

    有用于更复杂结构的集合模块,但在 Perl 中,将 Arrays 用于数组、堆栈和列表是一种常见的风格。 Perl 内置了将数组用作堆栈或列表的函数:push/pop、shift/unshift、splice(在中间插入或删除)和用于迭代的 foreach 形式。

    Perl 还有一个映射,称为哈希映射,它相当于 Python 中的字典 - 允许您在单个键和单个值之间建立关联。

    Perl 开发人员经常组合这两种数据结构来构建他们需要的东西——需要多个值?将数组引用存储在哈希表(Map)的值部分。可以以类似的方式构建树 - 如果您需要唯一键,使用多级哈希图,或者如果您不使用嵌套数组引用。

    Perl 中的这两种原始集合类型没有面向对象的 api,但它们仍然是集合。

    如果您查看 CPAN,您可能会发现提供其他面向对象数据结构的模块,这实际上取决于您的需要。除了 List、Stack 或 Map 之外,您还需要特定的数据结构吗?如果您询问特定的数据结构,您可能会得到更准确的答案(例如特定模块)。

    忘了提一下,如果您正在寻找跨多种语言的小型代码示例,PLEAC(类似的编程语言示例食谱)是一个不错的资源。

    【讨论】:

    • Perl 使用术语“hash”,而不是“hashmap”或“hashtable”。请不要使用“map”,因为这是用于列表操作的内置函数的名称。
    【解决方案2】:

    我赞同 Michael Carman 的评论:当您指的是散列或关联数组时,请不要使用术语“Hashmap”或“map”。尤其是当 Perl 有 map 函数时;这只会让事情变得混乱。

    话虽如此,Kyle Burton 的回应基本上是合理的:散列或数组,或者由两者混合组成的复杂结构通常就足够了。 Perl 了解 OO,但不强制执行;一个松散定义的数据结构可能足以满足您的需要。

    如果做不到这一点,请更准确地定义“计算每个元素的集合级别属性”的含义。请记住,Perl 有诸如 map 和 grep 之类的关键字,可让您进行函数式编程,例如

    my $record = get_complex_structure();
    # $record = {
    #    'widgets' => {
    #        name => 'ACME Widgets',
    #        skus => [ 'WIDG01', 'WIDG02', 'WIDG03' ],
    #        sales => {
    #            WIDG01 => { num => 25, value => 105.24 },
    #            WIDG02 => { num => 10, value => 80.02 },
    #            WIDG03 => { num => 8,  value => 205.80 },
    #        },
    #    },
    #    ### and so on for 'grommets', 'nuts', 'bolts' etc.
    # }
    
    my @standouts =
        map { $_->[0] }
        sort {
            $b->[2] <=> $a->[2] 
         || $b->[1] <=> $a->[1]
         || $record->{$a->[0]}->{name} cmp $record->{$b->[0]}->{name}
        }
        map {
            my ($num, $value);
            for my $sku (@{$record->{$_}{skus}}) {
                $num   += $record->{$_}{sales}{$sku}{num};
                $value += $record->{$_}{sales}{$sku}{value};
            }
            [ $_, $num, $value ];
        }
        keys %$record;
    

    从后往前阅读,这个特殊的Schwarztian transform 做了三件事:

    3) 它获取 $record 的密钥,遍历此任意结构中定义的 SKU,并计算出交易的总数和总价值。它返回一个匿名数组,其中包含密钥、交易数量和总值。

    2) 下一个块接收多个数组引用并对它们进行排序 a) 首先通过以数字方式按降序比较总值; b) 如果值相等,则通过比较交易数量,按数字降序排列; c) 如果失败,则按与此订单关联的名称进行 asciibetically 排序。

    1) 最后,我们从排序后的数据结构中取出 $record 的键,并将其返回。

    很可能你不需要单独设置一个类来做你想做的事。

    【讨论】:

      【解决方案3】:

      我通常会使用 @array 或 %hash。

      您正在寻找那些没有提供的功能?

      【讨论】:

        【解决方案4】:

        根据您需要如何访问对象来决定。如果将它们推到一个数组上,索引到它们,弹出/移出它们是可行的,那么使用一个数组。否则,通过某个键对它们进行散列或将它们组织成满足您需要的对象树。对象哈希是 Perl 中一种非常简单、强大且高度优化的处理方式。

        【讨论】:

          【解决方案5】:

          由于 Perl 数组可以很容易地追加、调整大小、排序等,它们足以满足大多数“收集”需求。如果您需要更高级的东西,通常可以使用哈希。在您真正需要之前,我不建议您去寻找一个收集模块。

          【讨论】:

            【解决方案6】:

            数组或散列都可以存储对象的集合。如果您想以某些方式与班级合作,班级可能会更好,但您必须先告诉我们这些方式是什么,然后我们才能提出任何好的建议。

            【讨论】:

              【解决方案7】:

              我会坚持使用 ARRAY 或 HASH。

               @names = ('Paul','Michael','Jessica','Megan');
              

              my %petsounds = ("cat" => "meow",
                           "dog" => "woof",
                           "snake" => "hiss");
              

              source

              【讨论】:

                【解决方案8】:

                这取决于很多;有Sparse Matrix 模块,persistence 的某些形式,new style of OO 等 大多数人只是使用perldataperllolperldsc 来回答他们关于数据结构的具体问题。

                【讨论】:

                  猜你喜欢
                  • 2013-02-16
                  • 2011-07-27
                  • 1970-01-01
                  • 2014-03-28
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-03-16
                  • 2011-04-05
                  • 1970-01-01
                  相关资源
                  最近更新 更多