Regarding the title, this is incorrect. Map keys are not functions; keywords are functions that take an associative data structure and will look themselves up in it. So, the premise here is not even correct to start.Usually we prefer to work by starting from a problem and consider alternatives, but as you state below, you don't have a problem in mind.
On Monday, November 13, 2017 at 3:49:41 AM UTC-6, Stephen Feyrer wrote:Hi there,This is possibly a silly question (and may have been asked before but I couldn't find earlier examples) so here it goes.
Get the nth element of the vectoruser=> (3 [1 "is" the :same]):sameNote that you can do something similar now with:([1 "is" the :same] 3)
Whereas in the situation with maps, keywords (a specific common key type) are functions, here you are implying that anything could implicitly be invokable as a lookup function on an associative data structure. This doesn't make a lot of sense to me and would undoubtedly have performance effects. Maybe there is some case like `(map 1 [[:a 0] [:b 1] [:c 2]])` where this would make sense. But this doesn't make sense for all indexed data structures, just those indexed by longs. Layering invocability on longs would require special handling in the compiler (Keywords are a type that embeds this by implementing IFn naturally, so it's not a special case).Get the nthiness of an element in the vectoruser=> (::same [1 "is" the :same])3This is something completely different - a linear search for a match. Clojure has considered and rejected making linear searching easier multiple times. It's almost always a sign that you are using the wrong data structure in the first place and should be using a hashed data structure instead. There is no chance we would do something like this.
Get the nthiness of an element in the vectoruser=> (:1 [1 "is" the :same])(0 2)I don't even understand what is intended here.
Taking things further into the realms of really you should have stopped there!Get the these element of the vectoruser=> ((1 3) [1 "is" the :same])("is" :same)Just for fun I tried:user=> ((:this :the) {:this "is" :the "same"})NullPointerException user/eval786 (NO_SOURCE_FILE:1)
I may be barking up the wrong tree or possibly just barking... I hope what I'm asking makes some sort of sense.Not particularly.By way of apology to the reader, when I began writing this question it was ill thought out and seemed a lot simpler. As a disclaimer, I can't think of direct examples how this would improve readability or such or even necessarily be useful.Seems like that should have been a sign. :)
CarrotColonel MustardSugar
Binky
Mr. NedGo Faster StripesStickScary Monster Not Technically A Horse
Binky
Updating subject to make it make more sense, hopefully.On 13 November 2017 at 14:15, Alex Miller <al...@puredanger.com> wrote:Regarding the title, this is incorrect. Map keys are not functions; keywords are functions that take an associative data structure and will look themselves up in it. So, the premise here is not even correct to start.Usually we prefer to work by starting from a problem and consider alternatives, but as you state below, you don't have a problem in mind.Normally, I don't offer possible solutions when I enquiring about a problem. Maybe with forethought context and or constraints...This is more of a solution (based on a lack of understanding) without a problem. If you like the problem I'm hoping to address is to reduce my lack of understanding.
On Monday, November 13, 2017 at 3:49:41 AM UTC-6, Stephen Feyrer wrote:Hi there,This is possibly a silly question (and may have been asked before but I couldn't find earlier examples) so here it goes.Get the nth element of the vectoruser=> (3 [1 "is" the :same]):sameNote that you can do something similar now with:([1 "is" the :same] 3)This works for me :)
Whereas in the situation with maps, keywords (a specific common key type) are functions, here you are implying that anything could implicitly be invokable as a lookup function on an associative data structure. This doesn't make a lot of sense to me and would undoubtedly have performance effects. Maybe there is some case like `(map 1 [[:a 0] [:b 1] [:c 2]])` where this would make sense. But this doesn't make sense for all indexed data structures, just those indexed by longs. Layering invocability on longs would require special handling in the compiler (Keywords are a type that embeds this by implementing IFn naturally, so it's not a special case).Get the nthiness of an element in the vectoruser=> (::same [1 "is" the :same])3This is something completely different - a linear search for a match. Clojure has considered and rejected making linear searching easier multiple times. It's almost always a sign that you are using the wrong data structure in the first place and should be using a hashed data structure instead. There is no chance we would do something like this.Perhaps, I'm not understanding vectors properly. A vector is a set of ordered elements, I think that is right.
Then at some point you might want to get one of those elements picking it out by its index. Equally, this is probably where I've lost the plot you might want to know where in a vector your element is residing.
Get the nthiness of an element in the vectoruser=> (:1 [1 "is" the :same])(0 2)I don't even understand what is intended here.You've already covered this above but I'll explain what I meant (just to be clear).user=> (nth [1 "is" the :same] 2)
1Anduser=> ([1 "is" the :same] 0)
1Therefore, a lookup of value '1' would return the indices for both occurrences in a list.
Taking things further into the realms of really you should have stopped there!Get the these element of the vectoruser=> ((1 3) [1 "is" the :same])("is" :same)Just for fun I tried:user=> ((:this :the) {:this "is" :the "same"})NullPointerException user/eval786 (NO_SOURCE_FILE:1)The thought here was the same as the above only with a list of invocations to return a list of values.
I may be barking up the wrong tree or possibly just barking... I hope what I'm asking makes some sort of sense.Not particularly.By way of apology to the reader, when I began writing this question it was ill thought out and seemed a lot simpler. As a disclaimer, I can't think of direct examples how this would improve readability or such or even necessarily be useful.Seems like that should have been a sign. :)That was one yes, the other was the suggestion that this might be a silly question. In hindsight, I think the question I'm looking at now maybe quite different to the one I thought I had when I started.At this point I think I would ask, how do you find the indices of elements within a vector for a certain value?
Or perhaps, should you be needing to obtain the positional component of a value, what would be the correct data structure to use?
For example, you're given a list (in an unspecified form) of horses from a race in their finishing order.CarrotColonel MustardSugarBinkyMr. NedGo Faster StripesStickScary Monster Not Technically A HorseBinkyThen (using Clojure) you're asked to get the positional value of 'Go Faster Stripes' or 'Binky'?
(.indexOf ["a" "b"] "b")
=> 1
(.indexOf ["a" "b" "b"] "b")
=> 1
Note how indexOf searches for the index of the first value which matches value.
To do what you ask, is a query over a vector, which requires a search on each element. This will take O(N) time. For a small list like in your example its probably good enough and not an issue.
If you want the name of the horse in a given position, that's a key lookup, which is ~O(1) time. You can use get:
(get ["a" "b"] 1)
=> "b"
If you really needed performance, you would need to combine a LinkedList and a map. Some datastructures do it for you under the hood, like Apache LinkedMap, amalloy ordered, java LinkedHashMap, etc.
Its possible to also just use sorted-map-by in a closure. But this only works if you're not going to add/update things to the datastructure after first creation.
See the example on clojuredocs: https://clojuredocs.org/clojure.core/sorted-map-by#example-542692d5c026201cdc327094
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
I don’t think anyone addressed your question about finding all the indices in a vector where the element matches a given search value?
There are a number of ways to tackle that (given it’s going to be a linear search). Since you want the indices, you are either going to need to track them directly or use map-indexed to produce them automatically.
(defn indices [x l] ; produces a vector
(loop [i 0 l l r []]
(if (seq l)
(recur (inc i) (rest l) (if (= x (first l)) (conj r i) r))
r)))
(defn indices [x l] ; produces a lazy sequence
(keep identity (map-indexed (fn [i v] (when (= x v) i)) l)))
(defn indices [x l] ; produces a vector
(transduce (comp (map-indexed vector)
(filter (comp (partial = x) second))
(map first))
conj
[]
l))
Hopefully that’ll give you some options to think about…
Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood