Given an elm list like:
twoDimensionalList =
[ [ 'U', 'U', ' ' ]
, [ ' ', ' ', ' ' ]
, [ ' ', ' ', ' ' ]
]
How can I update the ' ' in the first row with 'U' within an Elm List? I do not want to use an array I want to figure out how to do this with a List. I've already done the convert List to array and use set. I'm trying to learn how I'd update at a certain element in a list this time.
I started to think about how I might do this but just can't get there:
row1 =
take 0 twoDimensionalList
row1Updated =
indexedMap \i row1 -> if i == 2 then --somehow update this item in the map with 'U'
For this particular scenario, I would just pattern match on the list, bind the parts I want to preserve to variables, then reconstruct it with my replacement value:
case twoDimensionalList of
[ a, b, _ ] :: tail ->
[ a, b, 'U' ] :: tail
_ ->
twoDimensionalList
Basically, the :: operator (called "cons") will match or bind the first element (called "head") on the left of it, and the rest of the list (the "tail") on the right. So "a" :: ["b", "c"] will match the list ["a", "b", "c"].
The list literal syntax ([...]) in a pattern will match a list of exactly that size. So the [a, b, _] :: tail will match a list with the first ("head") element itself being a three-element list where the first two elements are bound to the variables a and b and the third element, which we're going to replace, is ignored. The rest of the outer list is then bound to tail.
The list is then reconstructed using pretty much the same syntax. The list literal syntax I'm sure you're familiar with, and the cons operator (::) works similarly to its pattern form, adding the element on the left to the list on the right, e.g. "a" :: ["b", "c"] will return the list ["a", "b", "c"]
Related
I have simple list that contains inside list
let ftss = [
["a","aData"],["b","bData"]
]
I want to iterate and access the elements "a" and "aData" etc.
I tried
List.iter (fun item ->
for i in 0..1 do
printfn "%s" item[i])
how do i access the elements inside the internal list?
Thanks
So, 1st thing is a comma isnt a delimter in a list, but in a tuple ',' so
let ftss = [
["a","aData"],["b","bData"]
]
is actually of type
val ftss: ((string * string) list * (string * string) list) list =
i.e. its a list of 1 entry of a tuple of a list of 1 entry each of a tuple.
which I THINK isnt what you intended?
I THINK you want (a ';' or new line delimits each entry)
let ftss3 = [
["a";"aData"]
["b";"bData"]
]
which is
val ftss3: string list list = [["a"; "aData"]; ["b"; "bData"]]
i.e. a list of a list of strings.
(I'd try to use FSI to enter these things in, and see what the types are)
so to iterate this list of lists you would go
List.iter (fun xs ->
List.iter (fun x ->
printfn "%s" x)
xs)
ftss3
As pointed out in the existing answer, you probably want to represent your data as a list of lists, for which you need to use the ; delimiter (to make a list) rather than , to construct a singleton containing a tuple.
I would just add that if you want to perform an imperative action with each of the items, such as printing, then it is perfectly reasonable to use an ordinary for loop:
let ftss = [
["a"; "aData"]; ["b"; "bData"]
]
for nested in ftss do
for item in nested do
printfn "%s" item
I've a field made of list of lists like this:
let list1 = ["a", "abcdefgh", "abc"]
I want to get a new field 5x5 such that there could be more then 5 lines or columns, but no less. It must be produced from the previous one by addition spaces ' ' or keeping them as they are, if there are more then 5 symbols. For additional lines no spaces needed. For example:
list2 = ["a ", "abcdefgh", "abc ", " ", " "]
or:
let list1 = ["a", "abcdefgh", "c", "d", "e", "f"]
list2 = ["a ", "abcdefgh", "c ", "d ", "e ", "f"]
I thought about map, replicate, and length, but I'm a little bit confused.
If it's possible, don't use libs (or use Data.Map only). Thank you
You need to determine the length of the strings. You can do this for example with a lambda expression, so then the mapping looks like:
func :: [String] -> [String]
func mylines = map (\x -> … ) linesOfFiles ++ replicate (5-length mylines) (replicate 5' ')
where x is thus string that will be mapped, and … is an expression to what that value is mapped. I leave filling in … as an exercise.
Usually it is better not to work with length: length takes linear time, and for infinite lists, this will even get the program into an infinite loop.
You can work with recursion to perform padding, something like:
padding :: Int -> a -> [a] -> [a]
padding 0 _ xs = …
padding n x [] = …
padding n x (x:xs) = …
to clarify my dilemma I'll explain the problem I'm faced with...
Basically, I am being passed a string that can contain single characters or ranges of characters and am trying to return back a list of characters represented by the string I was passed.
Ex. "b" would just give a list ['b'] "a-z" would give ['a' ; 'b' ; 'c' ; ... ; 'z'] and something like "ad-g2-6" would be ['a' ; 'd' ; 'e' ; 'f' ; 'g' ; '2' ; '3' ; '4' ; '5' ; '6'] since there is the character a and the ranges d-g and 2-6. (Also worth noting that something like "a-" would just be ['a' ; '-'] since the range wasn't completed.
My ideas for solving this have come to exploding the string into a list of characters (lst) then pattern matching and building onto an accumulator like
let mainfunc str = let lst = (explode str) in
let rec func lst acc = match lst with
| [] -> acc
| a::'-'::b::t -> func t (acc # **SOMETHING TO GET THIS RANGE**)
| a::t -> func t (acc # [a])
in func lst []
Anything that could help me get a range between the characters would be great and I'm open to ideas if someone has a better way to go about this problem than what I have set up.
(Also note that my explode function works as intended and converts a string into a char list)
Since you wrote a successful explode function I'll assume that you have no trouble with recursion etc. So the problem might just be a way to talk about characters as values (so you can get the next character after a given one).
For this you can use Char.code and Char.chr (from the OCaml standard library).
Here's a function that takes a character and returns a list consisting of the character and the next one in order:
let char_pair c =
[ c; Char.chr (Char.code c + 1) ]
Here's how it looks when you run it:
# char_pair 'x';;
- : char list = ['x'; 'y']
(I leave as an exercise the problem of dealing with the character with code 255.)
As a side comment, your approach looks pretty good to me. It looks like it will work.
del rec[1][1]
Is this the way to delete an item from a list of lists???
[ ['a','b','c'],
['d','e','f'],
['g','h','i'] ]
I want to delete b, e and h. How should I do that???
You can remove 'b', 'e' and 'h' by doing this
# the main list of lists
list1 = [ ['a','b','c'], ['d','e','f'],['g','h','i'] ]
for x in xrange(len(list1)):
del_list = list1[x][1]
while del_list in list1[x]: list1[x].remove(del_list)
print((list1))
Output
[['a', 'c'], ['d', 'f'], ['g', 'i']]
This was easy since the entries were exactly at the 2nd positions of the sublists of list1.
You could use .pop(i) method, where 'i' is an iterator.
rec = [ ['a','b','c'],
['d','e','f'],
['g','h','i'] ]
for i in range (0, len(rec)):
print rec[i].pop(1)
Note that .pop() method also returns that item.
The above code will result in :
b
e
h
See code below:
set k [list]
foreach i [list 1 2] {
lappend k [ list "hey" [ list "ho" [ list $i ] ] ]
}
puts [ join $k ",and,"]
exit
The result is:
hey {ho 1},and,hey {ho 2}
But I expected the result to look like:
hey {ho {1}},and,hey {ho {2}}
Any ideas why is that so?
Thanks.
If anyone of the list command's arguments are more than elements one, then only that corresponding indexed element's return value will have the braced list form.
% list a b c; # All list args are having only single element
a b c
% list "a" "b" "c"; # Same as above
a b c
% list {a} {b} {c}; # Same again...
a b c
% list "a b" c d; # Here, 1st arg is having 2 elements.
{a b} c d
%
Tcl's wiki page already mentioned about bizarre behavior of the nested lists in only one case, which is
% list [list [list x]]
x
It means that Tcl lists alone cannot be used to represent ALL kinds of data structures, as Tcl lists magically collapse when it's a series of nested lists with the terminal list having only a single bare word that requires no escaping.
Update :
More importantly, if the arg is having a space in it,
% list "x "
{x }
% list "x"
x
%
Since the space has to be considered as well, Tcl has no other way, but to enclose the braces.