TL;DR The expression find(a == 3) >= 0
will be true
iff the array a
contains 3
.
If a
is sorted, you can do the same thing in two lines using the search
function; theoretically this is faster (O(log n)
versus O(n)
, where n
is the length of a
):
int ii = search(a, 3);
bool a_contains_3 = (ii >= 0 && a[ii] == 3);
You can use the find
function here with one additional piece of information from the documentation:
Asymptote includes a full set of vectorized array instructions for
arithmetic (including self) and logical operations. These
element-by-element instructions are implemented in C++ code for speed.
Given
real[] a={1,2};
real[] b={3,2};
then a == b
and a >= 2
both evaluate
to the vector {false, true}
. To test whether all components of a
and b
agree, use the boolean function all(a == b)
. One can also use
conditionals like (a >= 2) ? a : b
, which returns the array {3,2}
, or
(a >= 2) ? a : null
, which returns the array {2}.
In particular, a == 3
will be broadcast, returning an array of booleans whose index i
entry tells you whether a[i] == 3
. Then, following the behavior quoted in the question, find(a==3)
will return the index of the first entry of a
equal to 3
, or -1
if there is no such entry. So find(a == 3) >= 0
returns true
iff the array a
contains the element 2
.
Using this, you can create the following intersect function that probably works (although I haven't actually tested to make sure it compiles or runs correctly):
int[] intersect(int[] a, int[] b) {
int[] intersection;
for (var w : a)
if (find(b == w) >= 0) intersection.push(w);
return intersection;
}
Here's an alternate approach that is faster in terms of big-O notation, but probably slower for many practical examples. (Again, I haven't tested to make sure it compiles, much less works correctly.)
int[] intersect(int[] a, int[] b) {
int sorted[], unsorted[], intersection[];
// Sort the shorter array:
if (a.length < b.length) {
sorted = sort(a); // Does not alter the original array.
unsorted = b;
} else {
sorted = sort(b); // Does not alter the original array.
unsorted = a;
}
// Iterate through the longer array and save the elements that are also
// in the shorter array.
for (var w : unsorted) {
int ii = search(sorted, w);
if (ii >= 0 && sorted[ii] == w) intersection.push(w);
}
return intersection;
}
find(a == 3)
returns 2, the index of the first occurrence of3
ina
.find(a == 3) > 0
returnstrue
iffa
contains3
.find(a == 3) > -1
, because0
is a valid index of the array.find(a == 3) >= 0
. Technically the functionality is documented, but not in a particularly user-friendly way. (Search that page for the word 'vectorized'.)