2015-04-28 2 views
0

У меня есть два списка:Clojure: IllegalArgumentException Ключ должен быть целым числом

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

и функция пытается получить элементы 1-го списка, которые являются частями элементов 2-го списка:

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

(в-массив XXA XXB) должен возвращать [ "OLP"]

но я получаю:

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

Я не понимаю, что это значит. Может кто-нибудь дает мне немного света?

+1

Если я запустил это в REPL, он возвращает '(« olp »)' - ошибка alomst означает, что (если вы также запускаете REPL), что вызывает другое определение. – peter

+0

Я запускаю это с помощью «против часовой стрелки». У меня есть только пять строк кода выше и 6-я строка с: «(print (in-array (xxa xxb)))» или «(in-array (xxa xxb))». – user3166747

+1

Если это ваш код, вы передаете свои векторы в 'in-array' неправильно. Попробуйте удалить круглые скобки вокруг них следующим образом: '(in-array xxa xxb)' – sp3ctum

ответ

4

Вот попытка сделать обсуждение выше четким ответом для тех, кто придет позже. Если я что-то пропустил, пожалуйста, дайте мне знать, или редактировать:

Начиная с исходного примера:

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 

И тогда, как питер указывает, дополнительный набор () вызовет эту ошибку:

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

Который содержит больше кода, чем требуется, чтобы показать ситуацию, поэтому мы можем обрезать его до:

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

Это минимальный случай, чтобы показать проблему. Если мы изменим этот пример, чтобы передать ожидаемый тип, мы увидим, что векторы, будучи вызванными как функция, берут число и рассматривают это число сами по себе.

user> (xxa 1) 
"xyz" 

Итак, наконец, мы можем исправить вызов и получить ожидаемый результат, почти точно:

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

В результате (ленивая) последовательность из for выражения и user3166747 просил вектор (не поленитесь, и произвольного доступа), который можно получить путем добавления вызова 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"] 

и теперь он точно соответствует.

Смежные вопросы