[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