【发布时间】:2010-09-12 21:14:42
【问题描述】:
有人可以推荐一个 perl 中可以用来存储对象集合的好模块吗?
或者 ARRAY 是否足以满足大多数需求?
更新: 我正在寻找一个集合类,因为我希望能够执行诸如计算每个元素的集合级别属性之类的操作。
由于我需要执行许多这样的操作,我不妨编写一个可以由单个对象扩展的类。这个类显然适用于数组(或者可能是哈希)。
【问题讨论】:
标签: perl collections
有人可以推荐一个 perl 中可以用来存储对象集合的好模块吗?
或者 ARRAY 是否足以满足大多数需求?
更新: 我正在寻找一个集合类,因为我希望能够执行诸如计算每个元素的集合级别属性之类的操作。
由于我需要执行许多这样的操作,我不妨编写一个可以由单个对象扩展的类。这个类显然适用于数组(或者可能是哈希)。
【问题讨论】:
标签: perl collections
有用于更复杂结构的集合模块,但在 Perl 中,将 Arrays 用于数组、堆栈和列表是一种常见的风格。 Perl 内置了将数组用作堆栈或列表的函数:push/pop、shift/unshift、splice(在中间插入或删除)和用于迭代的 foreach 形式。
Perl 还有一个映射,称为哈希映射,它相当于 Python 中的字典 - 允许您在单个键和单个值之间建立关联。
Perl 开发人员经常组合这两种数据结构来构建他们需要的东西——需要多个值?将数组引用存储在哈希表(Map)的值部分。可以以类似的方式构建树 - 如果您需要唯一键,使用多级哈希图,或者如果您不使用嵌套数组引用。
Perl 中的这两种原始集合类型没有面向对象的 api,但它们仍然是集合。
如果您查看 CPAN,您可能会发现提供其他面向对象数据结构的模块,这实际上取决于您的需要。除了 List、Stack 或 Map 之外,您还需要特定的数据结构吗?如果您询问特定的数据结构,您可能会得到更准确的答案(例如特定模块)。
忘了提一下,如果您正在寻找跨多种语言的小型代码示例,PLEAC(类似的编程语言示例食谱)是一个不错的资源。
【讨论】:
我赞同 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 的键,并将其返回。
很可能你不需要单独设置一个类来做你想做的事。
【讨论】:
我通常会使用 @array 或 %hash。
您正在寻找那些没有提供的功能?
【讨论】:
根据您需要如何访问对象来决定。如果将它们推到一个数组上,索引到它们,弹出/移出它们是可行的,那么使用一个数组。否则,通过某个键对它们进行散列或将它们组织成满足您需要的对象树。对象哈希是 Perl 中一种非常简单、强大且高度优化的处理方式。
【讨论】:
由于 Perl 数组可以很容易地追加、调整大小、排序等,它们足以满足大多数“收集”需求。如果您需要更高级的东西,通常可以使用哈希。在您真正需要之前,我不建议您去寻找一个收集模块。
【讨论】:
数组或散列都可以存储对象的集合。如果您想以某些方式与班级合作,班级可能会更好,但您必须先告诉我们这些方式是什么,然后我们才能提出任何好的建议。
【讨论】:
我会坚持使用 ARRAY 或 HASH。
@names = ('Paul','Michael','Jessica','Megan');
和
my %petsounds = ("cat" => "meow",
"dog" => "woof",
"snake" => "hiss");
【讨论】:
这取决于很多;有Sparse Matrix 模块,persistence 的某些形式,new style of OO 等 大多数人只是使用perldata、perllol、perldsc 来回答他们关于数据结构的具体问题。
【讨论】: