Created
September 21, 2009 19:20
-
-
Save nathany/190489 to your computer and use it in GitHub Desktop.
index-of-any, based on Stuart Halloway's Programming Clojure book, but with attempts in Python and Ruby (of course regex would be another, string-only, option)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Returns the index of the first character contained in searchChars | |
// From Apache Commons Lang, http://commons.apache.org/lang/ | |
public static int indexOfAny(String str, char[] searchChars) { | |
if (isEmpty(str) || ArrayUtils.isEmpty(searchChars)) { | |
return -1; | |
} | |
for (int i = 0; i < str.length(); i++) { | |
char ch = str.charAt(i); | |
for (int j = 0; j < searchChars.length; j++) { | |
if (searchChars[j] == ch) { | |
return i; | |
} | |
} | |
} | |
return -1; | |
} | |
// LOC 14, Branches 4, Exits Method 3, Local Variables 3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; map collection to vectors with [incrementing number, collection element] | |
(defn indexed [coll] | |
(map vector (iterate inc 0) coll)) | |
;; sequence comprehension returns idx when element is in the predicate sequence | |
;; sets are functions that test membership in the set (pred elt) | |
(defn index-filter [pred coll] | |
(when pred | |
(for [[idx elt] (indexed coll) :when (pred elt)] idx))) | |
(defn index-of-any [pred coll] (first (index-filter pred coll))) | |
;; LOC 6, Branches 1, Exits/Method 1, Local Variables 0 | |
;; try it out | |
(indexed "abcde") | |
(index-filter #{\a \b} "abcdbbb") | |
(index-of-any #{\a \b} "zzabyycdxx") | |
;; generalized, find the index of the 3rd "heads" coin toss | |
(nth (index-filter #{:h} [:t :t :h :t :h :t :t :t :h :h]) 2) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Python has indexed() built in, it's called enumerate(). | |
# A list comprehension and slice could do it in one line, | |
# so long as dealing with Iterable inputs. | |
def index_filter(predicate, collection): # throws a TypeError if not iterable (i.e. NoneType, int) | |
return [idx for (idx,elt) in enumerate(collection) if elt in predicate] | |
def index_of_any(predicate, collection): | |
return index_filter(predicate, collection)[0] # Warning: NoneType is unsubscriptable | |
print( index_filter("ab", "sabcdbbb") ) | |
print( index_of_any("ab", "zzabyycdxx") ) | |
# can't iterate over int, so insufficient to only check that not None: | |
# if predicate != None and collection != None: | |
# could catch and discard the error | |
try: | |
print( index_filter("ab", None) ) | |
except TypeError: | |
pass | |
# no :keywords, but still generalized... set {1} works in Python 3 but not 2.x, tuple works | |
print( "3rd heads:", index_filter((1,), [0, 0, 1, 0, 1, 0, 0, 0, 1, 1])[2] ) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# index_of_any turns out to be really easy, thanks to find_index | |
def index_of_any(predicate, collection) | |
collection.find_index {|item| predicate.include?(item)} | |
end | |
# the gotcha is strings aren't collections directly, | |
# so we need to call Ruby 1.9's chars() here or in the function (not generic!) | |
puts index_of_any %w{a b}, "zzabyycdxx".chars | |
# index_filter was more involved, and needs a temp collection | |
def index_filter(predicate, collection) | |
result = [] | |
collection.each_with_index do |item, index| | |
result << index if predicate.include?(item) | |
end | |
result | |
end | |
# or it could use an intermediary indexed() method like in the clojure version | |
def indexed(collection) | |
result = [] | |
collection.each_with_index {|item, index| result << [item, index] } | |
result | |
end | |
def index_filter_using_indexed(predicate, collection) | |
indexed(collection).map do |item,index| | |
index if predicate.include?(item) | |
end.compact # compact nils away | |
end | |
p indexed "abcde".chars | |
p index_filter %w{a b}, "sabcdbbb".chars | |
# then index_of_any just becomes a call to first() or a slice like Python | |
puts index_filter(%w{a b}, "zzabyycdxx".chars).first | |
# yup, generic, except the whole chars() thing | |
print "3rd heads:" | |
puts index_filter([:h], [:t, :t, :h, :t, :h, :t, :t, :t, :h, :h])[2] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment