<< Back to previous view

[CLJ-877] contains? is broken for vectors Created: 14/Nov/11  Updated: 14/Nov/11  Resolved: 14/Nov/11

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.3
Fix Version/s: None

Type: Defect Priority: Critical
Reporter: Jeff Palmucci Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: None

OSX Lion


contains? returns the wrong result for the last item in a vector:

user> (map #(contains? [1 2 3 4] %) [1 2 3 4])
(true true true false)

Comment by Steve Miner [ 14/Nov/11 12:41 PM ]

This is not a bug. Check the doc – contains? refers to the keys of the collection, not the values. For a vector, the "keys" are the indices.

user=> (map #(contains? [10 20 30 40] %) (range 4))
(true true true true)

Comment by Ben Smith-Mannschott [ 14/Nov/11 12:45 PM ]

This is a (common) misusing of contains?. Perhaps it would have been better if contains? had been named contains-key?, but that ship has sailed.

Usage: (contains? coll key)

Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or logarithmic time; it will not perform a linear search for a value. See also 'some'.

A vector of length 4 has four keys (indexes): 0, 1, 2, 3, which is why your example is returning (true true true false).

To get the behavior your are expecting from contains?, use some:

Usage: (some pred coll)

Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return :fred if :fred is in the sequence, otherwise nil: (some #{:fred} coll)

user> (map #(some #{%} [1 2 3 4]) [1 2 3 4])
(1 2 3 4) ; all of which are truthy

If you prefer booleans, you could do something like this:

user> (map (comp boolean #(some #{%} [1 2 3 4])) [1 2 3 4])
(true true true true)
Generated at Mon Sep 25 03:11:03 CDT 2017 using JIRA 4.4#649-r158309.