Reputation: 9856
I'm learning clojure and I love learning languages by example. But I do not like it just get a complete answer without me having to think about it.
So what I want is just some tips on what functions I might need and maybe some other clues.
The answer that I will accept is the one that gave me the necessary building blocks to create this.
public class IntervalMap<K extends Comparable<K>, V> extends
TreeMap<K, V> {
V defaultValue = null;
public IntervalMap(V defaultValue) {
super();
this.defaultValue = defaultValue;
}
/**
*
* Get the value corresponding to the given key
*
* @param key
* @return The value corresponding to the largest key 'k' so that
* " k is the largest value while being smaller than 'key' "
*/
public V getValue(K key) {
// if it is equal to a key in the map, we can already return the
// result
if (containsKey(key))
return super.get(key);
// Find largest key 'k' so that
// " k is the largest value while being smaller than 'key' "
// highest key
K k = lastKey();
while (k.compareTo(key) != -1) {
k = lowerKey(k);
if (k == null)
return defaultValue;
}
return super.get(k);
}
@Override
public V get(Object key) {
return getValue((K) key);
}
}
Update I want to recreate the functionality of this class
For examples you can go here: Java Code Snippet: IntervalMap
Upvotes: 2
Views: 265
Reputation: 7328
I'd be looking at some combination of:
(sorted-map & key-vals)
- will allow you to create a map ordered by keys. you can supply your own comparator to define the order.
(contains? coll key)
- tests whether a collection holds an item identified by the argument (this is a common source of confusion when applied to vector, where contains?
returns true if there is an element at the given index rather than the given value)
(drop-while pred coll)
lets you skip items in a collection while a predicate is true
Upvotes: 3
Reputation: 3378
A few things that I used in my implementation of an interval-get
function:
contains?
, like @sw1nn suggested, is perfect for checking whether a map contains a particular key.keys
can be used to get all of the keys in a map.filter
keeps all of the elements in a sequence meeting some predicate.sort
, as you have have guessed, sorts a sequence.last
returns the last element in a sequence or nil
if the sequence is empty.if-let
can be used to bind and act on a value if it is not falsey.The usage of the resulting function was as follows:
(def m {0 "interval 1", 5 "interval 2"})
(interval-get m 3) ; "interval 1"
(interval-get m 5) ; "interval 2"
(interval-get m -1) ; nil
Upvotes: 2
Reputation: 33657
If you want to implement the code block "conceptually" in clojure then the existing answers already answer your question, but in case you want the code block to be "structurally" same in clojure (i.e the subclassing etc) then have a look at gen-class
and proxy
in clojure documentation.
Upvotes: 0
Reputation: 34860
I would just use a map combined with a function to retrieve the closest value given a certain key. Read about maps and functions if you want to know more.
If you want to be able to mutate the data in the map, store the map in one of clojure's mutable storage facilities, for example an atom or ref. Read about mutable data if you want to know more.
You could use a function that has closed over the default value and/or the map or atom referring to a map. Read about closures if you want to know more.
The use of Protocols might come in handy here too. So, read about that too. Enough to get you going? ;-)
Upvotes: 2