Say I have a set like this:
#{#{"a"} #{"b"} #{"c"}}
Say I wanted to updated the middle set to make s become:
#{#{"a"} #{"be"} #{"c"}}
How would I achieve this?
(-> #{#{"a"} #{"b"} #{"c"}} (disj #{"b"}) (conj #{"be"}))
=> #{#{"a"} #{"be"} #{"c"}}
(of course there's no ordering in sets, it could well be shown in any order).
Related
I want to create helper function that modifies output returned by higher-order function.
Example of higher-order function:
(def use-meta-sub (make-app-fn (make-sub :meta)))
The problem is that when using this in let like this:
(let [meta-sub (use-meta-sub props :get-me-meta-of-this)])
returns map of key-value pairs like this:
{:key-we-almost-never-need-1 nil
:key-we-almost-never-need-2 nil
:key-we-almost-never-need-3 nil
:key-we-almost-never-need-4 nil
:meta-data {:something-useful "foo"
:more-usefull "bar"
:and-so-on "baz"}}
I would like to target only this :meta-data key
I tried this and some other variations:
(defn use-meta-data-sub [props ctrl]
(:meta-data (use-meta-sub props ctrl))) ;; both with get
It does not work because (I think, that returns lazy sequence and I do not know how to actually firs evaluate it and then extract the key from output).
Is this possible without editing 1st higher-order function, and other two it contains?
(I read all documentation on clojure site and clojure-unraveled, either I do not understand them, or they do not cover this)
My data structure was original a big Map. But I read that we should not use too big maps, to not run out of atoms. So my new data structure looks like that.
countries = [[{'name', 'Germany'}, {'code', 'DE'}], [{'name', 'Austria'}, {'code', 'AT'}]]
I want to make a filter_by/3 method, to filter this nested list for the country list by attributes name or code
Should I transform the Tuples to Maps or is there another way to filter this?
You could use a list of maps. Maps are very performant when retrieving elements, especially when the keys in a map are very few.
In your example:
countries = [%{name: "Germany", code: "DE"},
%{name: "Austria", code: "AT"}]
Note that even if you'll use thousands of such maps in a list, you'll never run out of atoms since :name and :code will always be the only two allocated atoms (since each atom is exactly is value, so writing :a and :a is like writing 3 and 3).
Once you have a similar list in place, you can filter it with a function like:
def filter_by(countries, key, value) do
Enum.filter(countries, fn(country) -> country[key] == value end)
end
filter_by(countries, :code, "AT")
I have a clojure list
("mykey:1" "mykey:2" "mykey:3")
I want to use redis mget to fetch values of all keys
(mget mykey:1 mykey:2 mykey:3)
I'm using the wonderful Carmine library.. I don't have any problem with it at all but when I try to use the list in a function
(defn get-keys
[k]
(mget k))
The key k actually includes the brackets too, since it's a list. Doing:
(mget (map #(%) k))
gets me nowhere either.
How do I now split them into individual keys so I can pass it to mget? is that possible?
Thanks
When you have a collection that contains values you want to use as the arguments to a function, you should use apply.
(def args '("mykey:1" "mykey:2" "mykey:3"))
(apply mget args)
; is equivalent to the call
(mget "mykey:1" "mykey:2" "mykey:3")
I am a beginner in Scheme so I apologize if it's a really basic question for you.
I am trying to create an empty list of lists which will be filled afterwards. The correct way to implement this is using objects but I need to do it using a list.
Suppose we have a university department and students. Each student has some specific fields such as name, gpa etc. These fields are determined by the user so the number of fields is unknown. At the end, we have something like we have in database structures:
create a table(table-name is given by the user as a parameter) with the columns(again, given by the user).
visually speaking, list of lists should look like this:
table-name---name1---name2---name3---...
-----------------field11----field21---field31--....
-----------------field12----field22---field32--....
.......
after creating the list, I should have the ability to insert records into it.
Just define a variable :
(define student-list '())
So student-list is the empty list. You can add whatever you want to it. Imagine you want add a student. You can just add it to the empty list :
(set! student-list (cons '(name phone-number etc) student-list))
You're just assigning to student-list a new value, which is the previous value of list (the empty list) and the new list you want. And, with the same code, you can add another student.
In Scheme, you don't have to determine the number of fields directly : list are dynamic structures. With (list stg stg2), you can create a list which is '(stg stg2). But you have another operator : cons. This function let you add something to a list : (cons 'stg3 (list stg stg2)), and you got the list '(stg3 stg stg2). You added a field and you don't had to "declare" a field or something like that. It's not a fixed array like in C. And if you have a list of list, each list can have a not defined number of fields. So, for example.
(define student-list)
;;; This is your first empty list.
(define (add-student ids)
(set! student-list (cons ids student-list)))
;;; ids is the list of name, etc. of student
;;; you want to insert in the student-list.
This code define a global variable and change it with the data you give to the function add-student. And this can be anything. '(name phone gpa) or '(name gpa), etc. However, if you want to pass a list to a function ((define (add-student students ids)) for instance, with students the list of all students), you can't use set!. You'll have to use set-car! and set-cdr!.
As said in comments, you don't have to set a list of nil elements, and complete them after. You can just have an empty variable, and fill it with your data when they come.
Edit : With the above code, I'm doing some side effect. But you have another way : in Scheme, everything has a return value. When you're doing (+ 1 2), you'll have the return value of 3. So if you do (list (+ 1 2) (+ 1 4)), you'll have a list '(3 5). So a function has a return value too. In above code, return value is #void, cause set! doesn't have return value. However, you can directly return the list you want. To do it, you can just remove the set!.
(define (add-student-second students ids)
(cons ids students))
So if you're doing (add-student-second '((name1)) (name2)), you'll got ((name2) (name1)) as a return value. You just have to treat your data as you want after that.
I wonder, how can I print in LISP each new value from loop "for" in new list, which each time creates by calling the function.
I have created the func:
(defun make (id name surname) (list :id id :name name :surname surname) )
Here I created the global variable:
(defvar *db* nil)
And here I defined the func for adding each new value to store it in db:
(defun add (cd) (push cd *db*))
So, I'm able to add each new data to db, like that:
(add (make 0 "Oleg" "Orlov" ) )
To look the content of my db , I can use:
*db*
So, I wonder how to put each new record-list to db using "for" loop, I print values in "for" loop in lisp like this:
(loop for i from 1 to 10 do ( ... ))
If , I use:
(loop for i from 0 to 10 do (add (make i "Oleg" "Orlov") ) )
If you read db using *db* you will see, that all evelen records were added, but after calling the last line, you will get NIL result in return.
Why do I catch NIL result, not T and what does it mean?
Thanks, best regards!
Every form in Lisp evaluates to something.
If a form you type in doesn't return a value, it will evaluate to NIL by default (otherwise, it evaluates to the value(s) it returns). Your loop doesn't actually return a value itself; it just performs 10 assignments (each of the intermediate expressions do return a value, but you don't collect and return them). Therefore, that code will return NIL.
If you haven't done so already, check out chapter 3 of Practical Common Lisp, in which Peter Seibel goes step-by-step through creating a simple database. It might give you some insights into the basics of how Lisp works. The specific question you ask (why forms return NIL by default, and what it means specifically in the context of Common Lisp) is answered in chapter 2 of the same book
As for how you would explicitly cause your loop to emit the list of items it added to *db*, try the following
(loop for i from 1 to 10
for elem = (make i "Oleg" "Orlov")
do (add elem)
collect elem)