Working on my first clojure project. I am fetching a large set of links with titles which I have put into a vector of maps which looks like:
[{:title: "A",:id 1,:link "https://example1.com"}
{:title: "B",:id 2,:link "https://example2.com"}
{:title: "C",:id 3,:link "https://example3.com"}
{:title: "AA",:id 4,:link "https://example4.com"}
{:title: "AB",:id 5,:link "https://example5.com"}
{:title: "AC",:id 6,:link "https://example6.com"}
{:title: "ABC",:id 7,:link "https://example7.com"}
{:title: "AAAA",:id 8,:link "https://example8.com"}]
I am now trying to find similar matching titles for each title within this same vector of maps. If they are sufficiently similar then I want to add their id to a new key in the map which contains something to hold a group of all similar id's. I was thinking a vector in a key would be idea for this.
For example: On first pass it would take title A and match it against title B, C, D, AA, BB, CC, ABC, AAAA. It would be close enough to AA, AB, AC, ABC, and AAAA we would say they are similar and add A's id into a new key for AA, AB, AC, ABC, and AAAA. I want to call this key :tags and ideally it would be a vector so it can easily contain multiple id's with the :tags key. The updated vector of maps would look like:
[{:title: "A",:id 1,:link "https://example1.com"}
{:title: "B",:id 2,:link "https://example2.com"}
{:title: "C",:id 3,:link "https://example3.com"}
{:title: "AA",:id 4,:link "https://example4.com", :tags [1]}
{:title: "AB",:id 5,:link "https://example5.com", :tags [1]}
{:title: "AC",:id 6,:link "https://example6.com", :tags [1]}
{:title: "ABC",:id 7,:link "https://example7.com", :tags [1]}
{:title: "AAAA",:id 8,:link "https://example8.com", :tags [1]}]
Then we would take title B on a second iteration and match it against all the titles, we can skip title A since we already compared them and if they were similar there would be a tag key with a 1 in its vector. During this pass it would only match titles AB & ABC. When this occurs I want to update the tags vector with the additional id so the vector of maps would now look like:
[{:title: "A",:id 1,:link "https://example1.com"}
{:title: "B",:id 2,:link "https://example2.com"}
{:title: "C",:id 3,:link "https://example3.com"}
{:title: "AA",:id 4,:link "https://example4.com", :tags [1]}
{:title: "AB",:id 5,:link "https://example5.com", :tags [1 2]}
{:title: "AC",:id 6,:link "https://example6.com", :tags [1]}
{:title: "ABC",:id 7,:link "https://example7.com", :tags [1 2]}
{:title: "AAAA",:id 8,:link "https://example8.com", :tags [1]}]
The order of the id's in the tags vector does not matter. After that pass it would move onto title C which would match 2 titles AC, and ABC. For each title it matches the id of title C would be added to the vector so our updated vector of maps looks like:
[{:title: "A",:id 1,:link "https://example1.com"}
{:title: "B",:id 2,:link "https://example2.com"}
{:title: "C",:id 3,:link "https://example3.com"}
{:title: "AA",:id 4,:link "https://example4.com", :tags [1]}
{:title: "AB",:id 5,:link "https://example5.com", :tags [1 2]}
{:title: "AC",:id 6,:link "https://example6.com", :tags [1 3]}
{:title: "ABC",:id 7,:link "https://example7.com", :tags [1 2 3]}
{:title: "AAAA",:id 8,:link "https://example8.com", :tags [1]}]
I am trying to avoid using simple loops to make this happen since I think there is a good way using the core clojure functions to do this. I was wondering if anyone had any simple ideas on how best achieve this without falling back on imperative programming loops.
I can easily see this being a simple for loop with 2 vars one for the original dataset and one for the modified. It would loop through the original and modify each matching title map tags key in the modified data set with the id's from the originals keys that match. This is not functional though and goes against best practices in clojure.
Any ideas on how this can be done in clojure using functional programming?
Thanks for the help!
{:title "A", :id 1,:link "https://example1.com"}
– jmargolisvt(println (vector { :link (str "HELLO") :title (str "HEE") :id 2 }))
Then it shows up as[{:link HELLO, :title HEE, :id 2}]
Without the println it shows as:(vector { :link (str "HELLO") :title (str "HEE") :id 2 })
Outputs[{:link "HELLO", :title "HEE", :id 2}]
Seems that println is removing the strings from the map entries. Updating the scenario to reflect how it should actually look. – Polar Bear