5

I have two lists:

(def xxa ["olp" "xyz"])
(def xxb ["ulove" "alove" "holp" "sholp"])

and a function trying to get the elements of the 1st list that are parts of elements of the 2nd list:

(defn in-array
  [array1 array2]
  (for [s1 array1 :when (some #(.contains %1 s1) array2)] s1))

(in-array xxa xxb) should return ["olp"]

but I get:

IllegalArgumentException Key must be integer  clojure.lang.APersistentVector.invoke

I don't understand what that means. Can someone gives me some light?

7
  • 1
    If I run this in a REPL it returns ("olp") - the error alomst certainly means (if you are also runnig in a REPL) that some other definition is causing the error. Commented Apr 28, 2015 at 7:45
  • I'm running this with "Counterclockwise". I have only the five lines of code above and a 6th line with : "(print (in-array(xxa xxb)))" or "(in-array(xxa xxb))". Commented Apr 28, 2015 at 7:53
  • 1
    If that is your code then you are passing your vectors to in-array incorrectly. Try removing the parentheses around them like so: (in-array xxa xxb) Commented Apr 28, 2015 at 8:23
  • 1
    I am not familiar with "Counterclockwise" but I have just tried it in the REPL in "nightcode" 0.4.7 and I get the result you expect! And, as @sp3ctum points out, in your original code you had (in-array xxa xxb) and in your comment (in-array (xxa xxb)). Commented Apr 28, 2015 at 8:26
  • 1
    In the second form above (in-array (xxa xxb)), Clojure is attempting to call xxa as function - which it can, arrays are functions of their indices, but those indices must be integers (hence the error), which xxb is not - try (xxa 1) to see that in action. Commented Apr 28, 2015 at 8:29

1 Answer 1

10

Here's an attempt to make the discussion above into a clear answer for those who come along later. If I've missed something please let me know or edit:

Starting with the original example:

user> (def xxa ["olp" "xyz"])
#'user/xxa
user> (def xxb ["ulove" "alove" "holp" "sholp"])
#'user/xxb
user> (defn in-array [array1 array2]
        (for [s1 array1 :when (some #(.contains %1 s1) array2)] s1))
#'user/in-array

And then as peter points out, an extra set of () would cause this error:

user> (in-array (xxa xxb))
IllegalArgumentException Key must be integer  clojure.lang.APersistentVector.invoke (APersistentVector.java:284)

Which contains more code than is required to show the situation, so we can trim it down to:

user> (xxa xxb)
IllegalArgumentException Key must be integer  clojure.lang.APersistentVector.invoke (APersistentVector.java:284)

which is a minimal case to show the problem. If we change this example to pass the expected type we can see that vectors, when called as a function, take a number and look that number up in themselves.

user> (xxa 1)
"xyz"

So finally we can correct the call and get the expected output, almost exactly:

user> (in-array xxa xxb)
("olp")

The result is a (lazy) sequence from the for expression and user3166747 had asked for a vector (non lazy, and random access) which we can get by adding a call to vec:

user> (defn in-array [array1 array2]
        (vec (for [s1 array1 :when (some #(.contains %1 s1) array2)] s1)))
#'user/in-array

user> (in-array xxa xxb)
["olp"] 

and now it matches exactly.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.