Indenting the code helps to reveal part of what's wrong. Unfortunately, you haven't stated what you're trying to accomplish, so it's hard to provide a full answer. I'm going to make some guesses, and I think that even if I guess incorrectly, what I say will help you sort out the problems.
@bsvingen is right that there's a missing parenthesis. However, my guess is that the problem is that there's an extra parenthesis before the first nth
. Don't you want =
to apply to the two expressions containing nth
? it doesn't. Instead, the first one is evaluated, and Clojure expects it to produce a function, because it appears at the beginning of a list. If we fix that, what results is:
(apply map +
(for [i (range (count frequencies-of-words-reviews))]
(for [j (range (count tokens))]
(if (= (nth frequencies-of-words-reviews i)
(nth tokens j))
nil)
0
1)))
However, that can't be what you intend, because in this case, the if
expression returns nil
if the condition is true, and if the condition is false, if
does its default for the "else", which is to return nil
. So the if
expression returns nil no matter what. However, this value is ignored anyway, as is the 0
. The code as I've rewritten is returns 1
for each element. So that's not what you intend, either.
Next, you don't need two for
's. You can use
(for [i ...
j ...]
...)
My guess is that what you're trying to test with =
is whether the keys of frequencies-of-words-reviews
are equal to the strings in tokens
, and that you're trying to count the cases in which you get equality. In that case, the code could look like this, with the addition of keys
in the 4th line.
(apply map +
(for [i (range (count frequencies-of-words-reviews))
j (range (count tokens))]
(if (= (nth (keys frequencies-of-words-reviews) i)
(nth tokens j))
0
1)))
(Note that the only way I was able to keep track of all of the parentheses and make sure that they were correct was by letting my editor format the code. When the resulting indentation isn't right, I know that I've done something wrong.)
However, there's still a problem. You define frequencies-of-words-reviews
to be a list whose first element is a hash map. This would usually produce an error, because Clojure assumes the first element of a list is a function. However, it turns out that hash maps are also treated as functions, so there's no error, but the result is that frequencies-of-words-reviews
has the value nil
. The solution is to quote the list:
(def frequencies-of-words-reviews
'({"charging" 1, "excellent" 2, "bit" 1, "great" 1}, {"bought" 1, "daughter" 1}))
or use a vector:
(def frequencies-of-words-reviews
[{"charging" 1, "excellent" 2, "bit" 1, "great" 1}, {"bought" 1, "daughter" 1}])
You need to do the same thing with tokens
:
(def tokens ["charging" "excellent" "bit" "great" "bought" "daughter"])
However, given my guesses, I think you need to merge the two hash maps. This will require some care if they have some of the same keys. merge-with
might be useful for this. I'm simply going to merge the two maps:
(def frequencies-of-words-reviews
(merge {"charging" 1, "excellent" 2, "bit" 1, "great" 1}, {"bought" 1, "daughter" 1}))
Finally, if you're trying to sum the values that result, you don't need apply map +
, you need apply +
or reduce +
. The result is:
(apply +
(for [i (range (count frequencies-of-words-reviews))
j (range (count tokens))]
(if (= (nth (keys frequencies-of-words-reviews) i)
(nth tokens j))
0
1))
This sums a bunch of 0's and 1's, and produces the result 30.
Other tips:
It would be more idiomatic to avoid indexing into sequences at all. Look at filter
, some
, set
, etc.