If switching to zsh is an option (that array=(values) syntax actually comes from zsh), then it's just a matter of:
intersection=( ${A:*B} )
subtraction=( ${A:|B} )
Or if the arrays may contain empty values and you want to preserve them, use the @ parameter expansion flag and double quotes (like for the Bourne shell's "$@"):
intersection=( "${(@)A:*B}" )
See typeset -U intersection to make the elements unique in the array. Or use the u parameter expansion flag to remove duplicates upon expansion.
${A:*B} expands to the elements of $A that are also found in $B. If the elements are not unique, then it's not necessarily the same as ${B:*A}. For instance, with A=(x x x) B=(x x), ${A:*B} yields x x x, while ${B:*A} yields x x. Even with distinct elements, the order may be different.
Example:
$ a=( a b c '' b c a '' ) b=( c B A '' A c b '')
$ i1=( ${a:*b} ) i2=( "${(@)a:*b}" ) i3=( "${(@u)a:*b}" ) s=( ${a:|b} )
$ typeset i{1..3} s
i1=( b c b c )
i2=( b c '' b c '' )
i3=( b c '' )
s=( a a )