Search code examples
arraysfactor-lang

Checking if a modified element of an array is a member in the same array


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?


Solution

  • 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.