Expand/Shrink

extract

Definition: sequence res = extract(sequence source, indexes, bool invert=false)
Description: Pick out a set of elements from a sequence according to the supplied set of indexes.

source : the sequence from which to extract elements.
indexes : a sequence of atoms, the indexes of the elements to be fetched in source.
invert : invert the indexes, see note below.

Returns a sequence, of the same length as indexes.
pwa/p2js: Supported.
Inversion: Index inversion is difficult to explain. Typically you will either know that you need it (and why), or you simply don’t need it.
The P-value correction task on rosettacode contains an example of use, in that case it is about putting things back where they belong after shuffling them about to do your thing (if you have a better explanation or example please feel free to pass it along).
Instead of using the indexes directly, they are used to construct the indexes to use: each (index[i])’th index gets i.
If indexes is {1,2,3} it behaves identically whether invert is true or not, because [1/2/3] get 1/2/3, which is the same.
However if indexes is {3,1,2} then [3/1/2] get 1/2/3, and it behaves as if {2,3,1} had been passed (and invert was false).
To clarify, ..,{3,1,2},true) [re-]creates indexes as {0,0,0} -> {0,0,1} -> {2,0,1} -> {2,3,1}, before being used.

If invert is true and sort(indexes)!=tagset(length(indexes)) then I expect an error would probably ensue, not that I can be adamantly certain of that.
Auillary function: sequence res = reinstate(sequence source, object indexes, replacements, bool invert=false)

Allows (for example) some previously extracted elements to be replaced, not necessarily but usually in the same order/slots.
While the (reinstate) example below emulates reverse(), and in fact the same effect could be achieved by using that routine on either the indexes or the results from extract(), it is probably more likely that you would manipulate the results from extract() before using reinstate() to put them all back in exactly the same place.
Note that the routine name replace() is already in use as an otherwise almost pointless compatibility routine for Euphoria, and obviously must not be confused with reinstate().

If indexes is an integer then replacements is the entire item to be put into that slot and invert must be false, otherwise a fatal error occurs if length(indexes)!=length(replacements) [except as below]. (It would be perfectly reasonable and straightforward to also allow eg reinstate(s,{1,2,3},4) to return s with [1..3] set to 4, should a real world use case of that ilk [all reps atom] ever arise, but for now an error is deemed probably more helpful. Likewise there may be calls for nested subscripts, eg reinstate(s,{{1,2,3}},4) to return s with s[1][2][3] set to 4, but y’know, [variable length] slice substitution and all that jazz probably needs a bit of design/thought, along with a decent set of tests.)

If source is {} and indexes is a sequence, source is replaced with repeat(0,max(indexes)) and then (and only then) a replacements of {} is replaced with tagset(length(indexes)), before of course performing the same processing as above, which can be used to create reverse index lookups.
For example reinstate({},{3,5,7},{}) returns {0,0,1,0,2,0,3}, ie res[3] is 1 which is the position where the 3 was in indexes.
You could have just done a find(3,indexes) instead, but in some cases that might not scale quite so well, or if you would have needed to make a copy anyway, you might as well convert it.
Examples:
?extract({11,13,15,17},{3,1,2,1,4}) -- prints {15,11,13,11,17}
string s = "nip"
?reinstate(s,{3,1},extract(s,{1,3})) -- prints "pin"
Implementation: See builtins\pextract.e (an autoinclude) for details of the actual implementation.