2

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

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

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

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

4

8 回答 8

4

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

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

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

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

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

忘了提一下,如果您正在寻找跨多种语言的小型代码示例,那么 PLEAC(Programming Language Examples Alike Cookbook)是一个不错的资源。

于 2008-09-24T20:36:24.107 回答
3

我会赞同 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;

从后往前阅读,这个特殊的施瓦茨变换做了三件事:

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

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

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

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

于 2008-09-25T01:31:37.687 回答
2

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

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

于 2008-09-24T20:32:52.773 回答
1

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

于 2008-09-24T20:31:48.267 回答
1

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

于 2008-09-24T20:33:13.647 回答
0

我会坚持使用数组或哈希。

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

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

来源

于 2008-09-24T20:29:46.243 回答
0

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

于 2008-09-24T20:35:43.623 回答
0

这取决于很多;有稀疏矩阵模块、某些形式的持久性、一种新的 OO 样式等大多数人只是 man perldataperllolperldsc来回答他们关于数据结构的具体问题。

于 2008-09-24T20:52:27.953 回答