我有 2 个阵列
a=(1,2,3,4,5)
b=(2,4)
输出应该是
c=(1,3,5)
(这应该是 ab 的结果)
我试过使用
unset a[${b}]
有任何想法吗?
我现在正在做的是一个循环,它运行了 700,000 次迭代
答案1
首先,如果你想进行 700,000 次迭代,你真的应该研究一下 bash 以外的内容。另外,您显示的不是 bash 中的数组,而是字符串1。数组以空格分隔,而不是逗号。
也就是说,这是一个 bash 方法,假设真正的数组:
a=(1 2 3 4 5)
b=(2 4)
c=( $(printf "%s\n" "${a[@]}" "${b[@]}" | sort | uniq -u) )
如果您实际上有逗号分隔的字符串而不是数组,请改用以下命令:
a=(1,2,3,4,5)
b=(2,4)
c=( $(sed 's/,/\n/g' <(printf "%s\n" "${a[@]}" "${b[@]}") | sort | uniq -u) )
或者,你可以使用 perl 来代替:
#!/usr/bin/perl
my @A=(1,2,3,4,5);
my @B=(2,4);
my %k;
map{$k{$_}++} (@A,@B);
my @C=grep($k{$_}==1,keys(%k));
print "@C\n";
1严格来说,它是一个具有一个元素的数组,但就 bash 而言,它本质上与字符串相同。
答案2
任务的复杂性(O(N ^ 2))无法降低;仅假设明确给出的内容(即,对于数组a
和的值没有假设b
),下面的代码将仅检查 中存在的每个值是否a
也存在于 中b
,如果该值存在,它将打破内部for
循环(给定假设下唯一可能的优化)并将该值添加到c
;如果有关于数组a
和内容的更多线索b
(即,如果每个数组中的值可能重复并且数组已排序),可能还有更多的改进空间:
#!/bin/bash
a=(1 2 3 4 5)
b=(2 4)
for i in ${a[@]}
do
match=0
for j in ${b[@]}
do
if [ "${i}" == "${j}" ]
then
match=1
break
fi
done
if [ "${match}" == 0 ]
then
c+=($i)
fi
done
echo ${c[@]}
答案3
方法perl
。此脚本显示数组中的所有元素a
,这些元素也包含在数组中b
。
#!/usr/bin/perl
my @a = (1,2,3,4,5);
my @b = (2,4,7,8,9,10);
# Create a hashmap with the entries in b as keys,
# but without values for the keys for a better lookup
# (exists ($hash{$element}))
my %hash;
@hash{@b}=();
foreach my $element (@a) {print "$element " unless exists($hash{$element})}
print "\n";
输出:
1 3 5
答案4
@terdon 接受的答案实际上并没有消除来自 的项目a
也位于 中b
,而是连接两个列表并删除非唯一值。当b
包含 中不存在的项目时,这是一个巨大的差异a
:c
将包含在 中b
但不在 中的值a
。
这是一个纯 Bash 解决方案移除其中的项目a
也在b
(请注意附加6
的b
):
a=(1 2 3 4 5)
b=(2 4 6)
c=( $(printf "%s\n" "${a[@]}" "${b[@]}" "${b[@]}" | sort | uniq -u) )
c
将由意外情况组成1 3 5
,但不包括意外情况6
。
如果数组项可能包含空格,请按照以下建议使用mapfile
构造Array3
Stack Overflow 上的 @David:
a=(1 2 3 4 5)
b=(2 4 6)
mapfile -t c < <(printf "%s\n" "${a[@]}" "${b[@]}" "${b[@]}" | sort | uniq -u)
请注意:这假设 中的所有值a
都是唯一的。否则它们将不会显示在 中c
。如果a
包含重复值,则必须先删除重复项(请注意1
中的重复项a
;如果您的项目包含空格,则可能使用mapfile
):
a=(1 1 2 3 4 5)
b=(2 4 6)
c=( $({ printf "%s\n" "${a[@]}" | sort -u; printf "%s\n" "${b[@]}" "${b[@]}"; } | sort | uniq -u) )
如果您想将 中的重复项复制a
到,请遵循@kos 的答案。如果和很大c
,情况也是如此:对于很多项目来说,这是一种非常低效的解决方案,即使对于少数项目(<100)来说它可以忽略不计。如果您需要处理大型数组,请不要使用 Bash。a
b