[pve-devel] applied: [RFC common 2/6] Add array_intersect and array_unique functions
Thomas Lamprecht
t.lamprecht at proxmox.com
Tue Jul 23 09:16:46 CEST 2019
On 7/17/19 3:03 PM, Stefan Reiter wrote:
> Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
> ---
> src/PVE/Tools.pm | 29 +++++++++++++++++++++++++++++
> 1 file changed, 29 insertions(+)
>
applied with some followups.
> diff --git a/src/PVE/Tools.pm b/src/PVE/Tools.pm
> index 4dd073f..c31ebeb 100644
> --- a/src/PVE/Tools.pm
> +++ b/src/PVE/Tools.pm
> @@ -1649,4 +1649,33 @@ sub dev_t_minor($) {
> return (($dev_t >> 12) & 0xfff00) | ($dev_t & 0xff);
> }
>
> +# Given an array of array refs [ \[a b c], \[a b b], \[e b a] ]
> +# Returns the intersection of elements as a single array [a b]
> +sub array_intersect {
> + my ($arrays) = @_;
> +
for convenience I allow now to just pass a list of references too.
> + return [] if @$arrays == 0;
> + return $arrays->[0] if @$arrays == 1;
While this normally is correct we still guard such array length
checks with a "scalar(@$arrays) to enforce scalar context (guards
against surrounding code change which would lift the scalar context
placed upon this by the "== 1"), just FYI.
> +
> + my $return_arr;
> + @$return_arr = array_unique(@{$arrays->[0]});
> + for my $i (1 .. $#$arrays) {
> + my %count = ();
> + foreach my $element (@$return_arr, array_unique(@{$arrays->[$i]})) {
> + $count{$element}++;
> + }
> + $return_arr = [];
> + foreach my $element (keys %count) {
> + push @$return_arr, $element if $count{$element} > 1;
> + }
followed up with:
last if scalar(@$return_arr) == 0; # empty intersection, early exit
> + }
> +
> + return $return_arr;
> +}
> +
> +sub array_unique {
made this one "private", it's relatively easy to do and so not much win
to have as public method of the already a bit crowded Tools.
Thanks!
> + my %seen = ();
> + return grep { ! $seen{ $_ }++ } @_;
> +}
> +
> 1;
>
More information about the pve-devel
mailing list