Accessing "columns" of 2d lists in dart - list

In a nested list, you can access what semantically would be "rows" by calling the nested list's indices as if it was one-dimensional:
//some nested list of type List<List<dynamic>>
print(nested)
//[["ColumnName0", "ColumnName1"], [0, 1], [0, 1]]
print(nested[0])
//["ColumnName0, "ColumnName1"]
Is there a similar shorthand to get ["ColumnName0", 0, 0]?

This is not a shorthand, but should work:
nested.map((s) => s[0]).toList()

Related

List of possible combinations of elements within a list of list

I have a list that contains 2 list:
[['JA#lazo.es', 'HI#lazo.es'], ['PO#jordi.es', 'GA#jordi.es'], '100', '1']
How I can combine all the possible combinations between the elements of the first list (position 0) and the second list (position 1) individually and at the same time create a new list with the elements that are not in those two positions of the original list.
So the result would be like:
[
['HI#lazo.es','PO#jordi.es','100', '1'],
['HI#lazo.es','GA#jordi.es','100', '1'],
['JA#lazo.es','PO#jordi.es','100', '1'],
['JA#lazo.es', 'GA#jordi.es','100', '1']
]
I can assume that the lists within the list will always be at position 0 and 1 but there could be multiple elements.
Thanks!
There are better ways to do this, but here is a simple way:
Create an array for storing all the results, and iterate the first array
all_arrays = []
for a in items[0]:
Iterate the second array
for b in items[1]:
Create a new array consisting of a, b, and the rest of your items; and append this array to the output
new_array = [a, b] + items[2:]
all_arrays.append(new_array)
For more reading on generating combinations of lists, I'd suggest checking out the itertools module

Move elements between lists by index number?

I'm trying to move elements between Lists in LoL (list-of-list) structure.
I can figure out how to select the list and move the elements, but I'm lost on how to reconstruct the resulting LoL back.
Here is partial function :
move(From, To, State=[P1,P2,P3], NewState=[NP1, NP2, NP3]) :-
nth1(From, State, FL), nth1(To, State, TL), move_elem(FL, TL, NewFL, NewTL),
.....whats here?...
.. NewState should be build out of NewTL,NewFL and one of P1,P2,P3...
.. the order of the lists should be preserved..
move_elem/4 is implemented. From & To are integers and specify the lists-at-position that will participate in the move op.
Currently LoL is list of 3 lists, but I would like it in the future to parametrize the number of lists.
State is LoL before the move, NewState is the LoL after the move.
?- move_elem([1,2,3], [4,5,6], F,T).
F = [2, 3],
T = [1, 4, 5, 6].
nth1/3 seems to be working OK.
?- L=[[1,2],[3,4],[5,6]], nth1(2,L,El).
L = [[1, 2], [3, 4], [5, 6]],
El = [3, 4].
move() shold move element from one of the three lists to another.
From and To are the index-of-the-lists f.e.
LoL = [[1,2],[3,4],[5,6]]
move(1,3, LoL, NewLoL)
NewLoL = [[2],[3,4],[1,5,6]]
move(2,1, LoL, NewLoL)
NewLoL = [[3,1,2],[4],[1,5,6]]
move the top element from list-1 to list-3.
Using length/2 and append/3:
move(From, To, State, NewState):-
length([_|HState], From),
length([_|HNewState], To),
append(HState, [[Item|L]|TState], State),
append(HState, [L|TState], MState),
append(HNewState, [NL|TNewState], MState),
append(HNewState, [[Item|NL]|TNewState], NewState).
The idea is to use length/2 to produce a list on uninstantiated variables of length From-1 and another of length To-1 (thus we skip one element from the lists of length From and To).
Then append/3 can be used to split State in two parts or to concatenate two lists.
The first call to append will split State in a list HState of From-1 elements, and a second list with the rest. The first element from the rest is further split in two parts (the item to move and the rest of that element).
The second call to append joins the two parts excluding the item to be moved.
The third and fourth calls to append repeat this idea though this time they are used to add the moved item to the target location.
You can implement move/4 in this way:
appendHead(T,H,[H|T]).
removeHead([_|T],T).
insert(_,_,_,_,_,[],[]).
insert(C,I2,L1,L2,C,[_|TI],[L1|TO]):-
C1 is C+1,
insert(C,I2,L1,L2,C1,TI,TO).
insert(I1,C,L1,L2,C,[_|TI],[L2|TO]):-
C1 is C+1,
insert(I1,C,L1,L2,C1,TI,TO).
insert(I1,I2,L1,L2,C,[HI|TI],[HI|TO]):-
I1 \= C,
I2 \= C,
C1 is C+1,
insert(I1,I2,L1,L2,C1,TI,TO).
move(I1,I2,LIn,LOut):-
nth1(I1,LIn,L1),
nth1(I2,LIn,L2),
nth1(1,L1,E1),
removeHead(L1,L1R),
appendHead(L2,E1,L2F),
insert(I1,I2,L1R,L2F,1,LIn,LOut).
?- LoL = [[1,2],[3,4],[5,6]], move(1,3, LoL, NewLoL).
LoL = [[1, 2], [3, 4], [5, 6]],
NewLoL = [[2], [3, 4], [1, 5, 6]].
false.
?- LoL = [[2], [3, 4], [1, 5, 6]], move(2,1, LoL, NewLoL).
LoL = [[2], [3, 4], [1, 5, 6]],
NewLoL = [[3, 2], [4], [1, 5, 6]].
false.
?- LoL = [[1,2],[3,4],[5,6]], move(2,1, LoL, NewLoL).
NewLoL = [[3,1,2],[4],[1,5,6]].
false.
If you want to prevent backtracking, just add a cut ! after each definition of insert/4 (you will not get false).
Prolog does a depth-first search, meaning it will try to reach a goal by exploring all possible paths to a solution. Every time there are multiple paths available, it creates a choice point and then works its way down through the choices top to bottom. That means, if a choice immediately fails, the next will be called. This allows you to create the paths very clearly and you can give it choices to make. All atoms including lists are effectively immutable in Prolog. What you want to do is construct a second list from the first, possibly in a different order or with less elements, more elements, replaced elements etc.
I'm using replacement of a cell in a row with a cell(point(X,Y),Value) coordinate in a matrix as an example here. The three choices for rebuilding a list.
End of the list has been reached, this is the end condition and ends the new list.
The first cell of the list is checked and the coordinate doesn't match the replacement, so it's placed as is in the new list.
The first cell of the list does match the coordinate so place the element in the new list and close it off by adding the remaining unchecked elements as the tail.
This results in the code:
%coordinate not found, return the list as is
replace_cell(_,_,[],[]).
%no match, X already extracted from Element to reduce calls
replace_cell(X, Element, [RowElement|Tail], [RowElement|NewTail]) :-
RowElement \= cell(point(X,_),_),
replace_cell(X, Element, Tail, NewTail).
%match
replace_cell(X, Element, [cell(point(X,_),_)|Tail], [Element|Tail]).
This is the standard recursion you're probably used to. A goal is set, an answer is reached and Prolog starts stepping back through the calls made, filling in the variables we left open as it steps back. Then those filled variables become the output to the next returned call.
To then do it with multiple layers of lists, we just need to figure out which list we need to pass to the next, more specific call. In this matrix example, it's a square so all columns share an X and all rows share an Y coordinate. To figure out which row we need, we can feed the entire matrix into a simple predicate which checks the Y. Note that we aren't actually modifying the matrix yet, just identifying the row. This is mostly to keep the code readable.
%are there any rows left?
move_to_row(_, [], []).
%is element's Y equal to row Y?
move_to_row(Y, [Row|_], Row) :- Row = [cell(point(_,Y),_)|_].
%move to next row
move_to_row(Y,[_|Tail], Row) :- move_to_row(Y,Tail,Row).
After replacing the element in the row, since we have both the old and the new row we can identify the old row and reconstruct the matrix with the new row.
replaceElement(_,_,[],[]).
replaceElement(Replacable, Replacement, [Item|List], [Replacable|NewList] ) :-
Item \= Replacable,
replaceElement(Replacable, Replacement, List, NewList),
replaceElement(Replacable, Replacement, [Replacable|List], [Replacement|List] ) :-
!.
So effectively, the position in the list is kept by the order in which we step through the list on the way down, and then the new list is rebuilt on the way up.
For list [1,2,3], [Head|Tail] gives us Head = 1, Tail = [2,3]. If we then call [Head|Tail] again, it gives us Head = 2, Tail = [3]. On the way back, the exact opposite happens and the Head is appended to the front of the Tail. By visualizing each layer of lists as its own identifiable type and giving them their own identifier, it should be fairly simple to go through them efficiently irregardless of how many lists within lists you want to nest. The matrix is a 2d rectangle, but for example by having the coordinates within cell as a list and adding a Z axis it can fairly easily be turned into a cube or something even more complex with more than 3 dimensions.

PROLOG - Change elements in a list

I need to change elements in a list, I have the following code:
change_aux(_,_,[],[]).
change_aux(X,Y,[X|T],[Y|S]):-!,change_aux(X,Y,T,S).
change_aux(X,Y,[Z|T],[Z|S]):-change_aux(X,Y,T,S).
flatten2([], []) :- !.
flatten2([L|Ls], FlatL) :-
!,
flatten2(L, NewL),
flatten2(Ls, NewLs),
append(NewL, NewLs, FlatL).
flatten2(L, [L]).
change(X,Y,[X1|Y1],[X2,Y2]):-
flatten([X1|Y1],L),
change_aux(X,Y,L,[X2|Y2]).
Input: change(2,5,[1,[2,[3,2],1]],R).
Print: R = [1, [5, 3, 5, 1]] .
But I need R to be printed like this: R = [1,[5,[3,5],1]]
Could you help me, please?
There are some problems in the code above like in definition change(X,Y,[X1|Y1],[X2,Y2]):- I don't think that the output list should always consists of two elements. Besides that the change_aux predicate needs some work since now it's just traversing the list and not building the nested output list. You could try something that would build recursively the nested levels of the list like:
change(_,_,[],[]).
change(X,Y,[H|T],[H|T1]):- \+is_list(H),dif(H,X),change(X,Y,T,T1).
change(X,Y,[X|T],[Y|T1]):- change(X,Y,T,T1).
change(X,Y,[H|T],[L|T1]):- is_list(H),change(X,Y,H,L),change(X,Y,T,T1).
Note that in the above predicate there is no need to use flatten/2 predicate since we take advantage of the nested levels of input list to build output list.
Example:
?- change(2,5,[1,[2,[3,2],1]],R).
R = [1, [5, [3, 5], 1]] ;
false.

To check if sublist exists in another list

coll = [[3, 3], [2, 2, 2], [2, 4], [2, 3], [2, 2]]
main = [4, 3, 3, 2, 2, 2, 2, 2, 2, 2]
I have 2 lists. 'coll' is a list of lists with each sublist containing integers which might have duplicates(ex- [2, 2, 2]). And main is a list containing integers. I want to check if the sublist elements of 'coll' are present in 'main' or not. For this case, it is true since [2, 2, 2], [3, 3] and other sublists are present. The order of elements in the sublist and 'main' doesn't matter. Whatever elements are present in sublist they may be present in 'main' in any position.
I cannot use sets because of the presence of duplicates. And also I cannot use strings because:
coll = ['222']
main = ['423262']
I have used a sample of sublist to show the problem with using string. My algorithm requirement is that in this case also 'true' is returned because '2' is present at 3 locations , index- 1, 2, 5. But:
if coll in main:
return True
else:
return False
this returns false if I use strings for checking.
Please suggest any method.
I think the most readable way to do that is to create a Counter instance for each of your sublists, and them check with the list "count" method if it matches the requirement for each argument of the sublist:
from itertools import Counter
def checksub(main, sublist):
c = Counter(sublist)
for num, count in c.items():
if main.count(num) < count:
return False
return True
all(checksub(main, sublist) for sublist in coll)
This is not fast - if you are iterating over a large data volume, you'd better use some approach that map the "main" list into a data-structure where the counting can be checked in a faster way tahn using "count". Or, if there are few distinct numbers, even something as simple as cache the returns of "count" for each different number.
Otherwise for small sizes of "main" this might suffice.
On a second reading of your question, it seems like you only require that one of the sublists be present in main - if that is the case, just replace the call to all for any above.

Does SML supports the nested list?

the Nested List can exist in Scheme, but is it legal to use nested-list in SML? or we can only use simple list in SML?
and if legal,
1) how to check wether the two input list have the same list structure. algorithm the atoms in the list are not equal.
2) Whatever the deep of the input list, how to delete all the atoms in the nested-list that equals to the input value: a. should use the original list and not create a new list.
There's no problem in having nested lists in Standard ML. For an example:
val foo = [ [1, 2, 3], [4, 5], [6] ]
is an example of an int list list, i.e., a list of lists of integers.
As for your additional questions.
1
If by same structure you mean whether the sublists contain the same number of elements, i.e, you want
val bar = [ [34, 4, 6], [2, 78], [22] ]
val baz = [ [1], [4, 6, 2], [3, 6] ]
val cmp_foo_bar = structureEq (foo, bar) (* gives true, since the lengths of the sublists match up *)
val cmp_foo_baz = structureEq (foo, baz) (* gives false, since they don't *)
Then you can simply make a recursive function on the lists, that compares the length of each sublist in turn.
Note, if the lists are nested more than once, you'll need a function for each level. (i.e., one for 'a list lists, one for 'a list list lists, etc.
2
You cannot make a function that "however deep the input list" does something to the elements in the list. The type system will not let you do this. This is similar to how you cannot make the following list:
val illegal_list = [ [1, 2], [ [1, 4], [2, 3] ] ]
This is due to a list only being allowed to contain one type of elements, so if you have an 'a list list, each element in the list must be an 'a list. You cannot have 'as directly.
You'll have to settle on how nested the lists are, and make a function specific to that depth.
There is no problem with nesting lists in SML, e.g. [[1, 2], [3, 4]] works just fine.
However, I suspect you actually mean something more general, namely the ability to nest "lists" in heterogeneous ways: [[1, [3]], 2]. This is not legal as such in SML. However, this is because such a thing is not really a list, it is a tree.
You can define trees easily as well, but you need a more general type definition than the one for list:
datatype 'a tree = L of 'a | T of 'a tree list
Then T[T[L 1, T[L 3]], L 2] is a representation of the "list" above. A function for computing the depth (or height) of such a tree looks like
fun depth (L _) = 0
| depth (T ts) = 1 + max (List.map depth ts)
where max needs to be defined in the obvious manner.