I have an array:
{ "abc" "def" "cba" "fed" "junk" }
I want to check if each item in the array has its reversed version as a member in the same array.
In Python, I would express this as:
>>> array = ["abc", "def", "cba", "fed", "junk"]
>>> [item for item in array if item[::-1] in array] # [::-1] reverses a string
['abc', 'def', 'cba', 'fed']
Or even:
>>> list(filter(lambda x: x[::-1] in array, array))
['abc', 'def', 'cba', 'fed']
I've tried:
IN: scratchpad dup [ dup reverse swap member? ] filter
--- Data stack:
{ "abc" "def" "cba" "fed" "junk" }
{ }
Nope, the quotation fails for each item.
I'm sure there's an obvious answer, or a combinator and quotation which does this efficiently. What is it?
Here you need a closure. The quotation that runs on each element needs to look at a value other than the element itself. A convenient syntax for writing closures is implemented using fried quotations.
E.g:
{ "abc" "def" "cba" "fed" "junk" } dup '[ reverse _ in? ] map
You bind the value from the stack at the "outside" to the _
spot on the "inside". You can construct and run an equivalent closure with with
or using curry
which is a more low-level word:
{ "abc" "def" "cba" "fed" "junk" } dup [ reverse swap in? ] with map
Then you add all?
to check that all values satisfies the predicate:
{ "abc" "def" "cba" "fed" "junk" } dup '[ reverse _ in? ] all?
USE: sets
to load the in?
word.