But that finds first location in L of each element in R.
However, what if we wanted the first b in R to "consume" the first b in L so that the second b in R would have to contend with the index of the second b in L`?
That is, we want some function which gives 2 1 3 5 6 7 4.
The first line is the data and the second is the indices of the first occurrences (i.e. all identical items will get the same index). The third line is the position that each will occupy when sorted. That means that identical elements get consecutive positions.
E.g. you can see that the first b gets 4 (because there are 3 as) and the second gets 5.
This almost solves the problem.
However, there are a couple of issues:
1. The two arrays must have the same set of elements.
2. The two arrays must have equally many of each unique element
3. The unique elements must initially occur in the same order
Why these conditions?
1. is because otherwise the purely numeric "labels" will match the wrong things.
2. is because otherwise one element's "label" will be paired up the the label of a different value element of the other array.
3. is because otherwise identical "labels" numbers refer to two entirely different things, and so the matching won't give a meaningful result.
But if these conditions are met, we get the right result:
The first a in R gets paired with the element in position 1 of L, and the second a in R goes with the element in position 3, and the third goes with the last element of L.
OK, let's have a stab at how we can ensure that all conditions are eliminated, and then we'll have our solution.
Since we're going to look up elements of R in L anyway, we can use indices into L (that is L⍳R) instead of the lookup of R into itself (R⍳R) This ensures that elements of R are labelled with "L's labelling system".
Notice that this sequence begins with what we want, and now we have equal proportions, so we've eliminated issue 2. We just need to reshape (or take) to chop the unneeded elements:
Now it works even though we have a d in R which doesn't occur in L. In accordance with the rules of ⍳, not-found elements get the index 1+the last index of the left argument. Since we chopped the left list of labels to the length of L, that's what we get.
One use case might be in a first-come, first-served queue... let's say you have First Class, Premium, and Economy seats on a plane. This algorithm will use them up in order as requests are processed
Now to take Brian's example of filling a plane with multiple classes, using first-come, first-serve, we may want to ask: For each customer, will he fit on the plane?
So, say we have a plane like '11bbbpeepee' where 1 is first class, b is business, p is economy plus (extra legroom at emergency exits), and e is regular economy.
And we have a bunch of customers coming to buy seats: '1bbbpppeeeee'. That's one 1st class customer, three business people, three want more legroom, and a load of regular people.
Being that the plane only has 11 seats, we can see that one plus and one economy will not fit (indicated by the 12s), but we just want a Boolean, not the actual seating.
So think about it. progressive dyadic iota (or iota without replacement) asks "For each element, where would it go in the remaining elements?" Now we need to ask "For each element, does it fit in (i.e. is it in) the remaining elements?"
@J.Sallé Good, yes, but we don't need to first calculate the indices.
"is it in" is APL's ∊. Just note that the arguments of ∊ and ⍳ are "reversed" in that the array we look up in is on the left for ⍳ and on the right for ∊, so we just swap the parts of our function and substitute ∊ for the middle ⍳: