getting values from nested lists in groovy - collections

I have a 3 level nested list in groovy like this
rList = [[[12, name1],[22,name2],[49,name3]],[[33, name5],[22,name6],[21, name7]]]
how can I iterate it to get the name values from the 1st sublist
so I want like rsublist = [name1, name2, name3]
Thanks in advance.

rList = [[[12, 'name1'], [22, 'name2'], [49, 'name3']], [[33, 'name5'], [22, 'name6'], [21, 'name7']]]
names = rList[0]*.getAt(1)
assert names == ['name1', 'name2', 'name3']
First, rList[0] gives you the first sub-list, which is [[12, name1], [22, name2], [49, name3]]. Then, the spread operator, *., is used to apply the same method, getAt(1), to every element of that list, which will return a list with every second element of the sub-lists, which are the values you were looking for :)
You can also use rList[0].collect { it[1] } which is equivalent and might be more familiar if you are not used to the spread operator.

Based on the #epidemian's answer, here's a more readable version:
rList.first()*.last()

Related

iterating 2D array in Elixir

I am new to Elixir language and I am having some issues while writing a piece of code.
What I am given is a 2D array like
list1 = [
[1 ,2,3,4,"nil"],
[6,7,8,9,10,],
[11,"nil",13,"nil",15],
[16,17,"nil",19,20] ]
Now, what I've to do is to get all the elements that have values between 10 and 20, so what I'm doing is:
final_list = []
Enum.each(list1, fn row ->
Enum.each(row, &(if (&1 >= 10 and &1 <= 99) do final_list = final_list ++ &1 end))
end
)
Doing this, I'm expecting that I'll get my list of numbers in final_list but I'm getting blank final list with a warning like:
warning: variable "final_list" is unused (there is a variable with the same name in the context, use the pin operator (^) to match on it or prefix this variable with underscore if it is not meant to be used)
iex:5
:ok
and upon printing final_list, it is not updated.
When I try to check whether my code is working properly or not, using IO.puts as:
iex(5)> Enum.each(list1, fn row -> ...(5)> Enum.each(row, &(if (&1 >= 10 and &1 <= 99) do IO.puts(final_list ++ &1) end))
...(5)> end
...(5)> )
The Output is:
10
11
13
15
16
17
19
20
:ok
What could I possibly be doing wrong here? Shouldn't it add the elements to the final_list?
If this is wrong ( probably it is), what should be the possible solution to this?
Any kind of help will be appreciated.
As mentioned in Adam's comments, this is a FAQ and the important thing is the message "warning: variable "final_list" is unused (there is a variable with the same name in the context, use the pin operator (^) to match on it or prefix this variable with underscore if it is not meant to be used)" This message actually indicates a very serious problem.
It tells you that the assignment "final_list = final_list ++ &1" is useless since it just creates a local variable, hiding the external one. Elixir variables are not mutable so you need to reorganize seriously your code.
The simplest way is
final_list =
for sublist <- list1,
n <- sublist,
is_number(n),
n in 10..20,
do: n
Note that every time you write final_list = ..., you actually declare a new variable with the same name, so the final_list you declared inside your anonymous function is not the final_list outside the anonymous function.

Loops in Python3.6

I want to print a specified element from each list until it stops, however I am not sure of what loop conditions to use.
Code
For example, I have printed element[0] of each list but I want it to loop until it prints all the elements.
Any help is appreciated.
Thanks
The following code is, maybe, the simplest solution to print all the cats. If you want to print a single list, use only the last 2 lines after replacing "l" with your list variable.
a = ['Ginger', 'Lion', 'Persian', 'Sphynx']
b = ['Mainecoon', 'Tiger', 'Ragdoll', 'Birman']
c = ['Lynx', 'Shorthair', 'Abyssinian', 'Scottishfold']
d = ['Ocelot', 'Jaguar', 'Chartreux', 'Korat']
lists = [a, b, c, d]
for l in lists:
for cat in l:
print(cat)

calling variable name of a dataframe inside functions in R using "$"

I have a dataframe(master) that has some variables which i have stored in the list below:
cont<-list("Quantity","Amt_per_qty","Trans_tax","Total_trans_amt")
catg<-list("Gender","Region_code","SubCategory")
I am trying to create a function where I can access the variables from dataframe and perform some function on them, though x and val in below function seems to resolve, how can I access the variables using the $ sign inside function
univar<-function (x){
for (val in cont){
print (val)
n<-nrow(x$val) }
print (n) }
univar(master)
Its returning NULL, I tried even with n<-nrow(x[,val]), that also don't seem to work.
i) x[val] returns a data.frame
ii) x[,val,drop = TRUE] returns a vector
iii) x[[val]] shall return as a vector. Advantage of this is : it also works with data.tables
n <- nrow(x) or length(x[[val]])
The reason is that the OP created a list, it could be unlisted and then use [
cont <- unlist(cont)
univar<-function(x){
for (val in cont){
print (val)
n<-nrow(x[[val]]) }
print (n) }
univar(master)

filling an array recursively in R language

I have a multidimensional array (B_matrix) that I need to fill up with some random values. Since the dimension depends on two parameters K and C that are user defined, I cannot use nested loop to fill the array, so I have decided to fill it up recursively.
The problem with the recursion function (fillUp) is that that even though the array is declared outside the function, the array is set to NULL after the function is run.
B_dim = rep(2,((K+1+C)*2))
B_matrix = array( dim = B_dim, dimnames = NULL)
string = c()
fillUp<-function(level, string ){
if (level>=1){
for(i in c(1,2)){
Recall(level-1, c(string, i))
}
}else{
B_matrix[string] = 1;
}
}
fillUp(length(B_dim), string)
> sum( B_matrix == 1)
[1] NA
I'm new to R, so I'm not sure if the "global" declaration allows fillUp to change the values of the matrix.
Edit:
Note that the line
B_matrix[string] = 1;
is just a test case, and the original idea is to assign some random value that depends of the position of the array element.
Edit2:
Based on what #Bridgeburners hinted, I'm almost there. Replacing B_matrix[string] = 1, by
assign('str', matrix(string,1), envir=.GlobalEnv)
assign('hl', B_half_length, envir=.GlobalEnv)
rul <-runif(1, 0, sum(str[1:hl]))
with( .GlobalEnv,B_matrix[str] <- rul)
I get the error (last line):
Error in eval(expr, envir, enclos) : object 'rul' not found
The problem, I guess, is that I'm working with variables from two different environments at the same time. I don't know how to proceed here.
This option doesn't work either
assign('str',matrix(string,1), envir=.GlobalEnv)
assign('hl', B_half_length, envir=.GlobalEnv)
assign('ru', runif(1, 0, sum(str[1:hl])), envir=.GlobalEnv)
with( .GlobalEnv,B_matrix[str] <- ru)
Note: no visible binding for global variable 'ru'
Edit3:
I've finally solved it:
assign('str',matrix(string,1), envir=.GlobalEnv)
with( .GlobalEnv, B_matrix[str] <- runif(1, 0, sum(str[1:B_half_length])-B_half_length+1) )
where B_half_length is a global variable
Whenever a process is working within a function, it's working in a different environment. The object "B_matrix" is defined in the global environment. Since you're nesting environments (2*(K+C+1) times) you're not impacting the original object. If you simply replace line
B_matrix[string] = 1;
with
assign('str', matrix(string,1), envir=.GlobalEnv)
with(.GlobalEnv,B_matrix[str] <- 1)
your code will work. You simply need to specify which environment your expression is working in. (In the first line you're passing the local value of "string" to a global object named "str".)
Note, also, that indexing an array with a vector doesn't work.
That is, "B_matrix[2,2,2,2,2,2]" is not the same as "B_matrix[c(2,2,2,2,2,2)]".
But it works with a matrix
What you want can be achieved with the following line code once you have initialised you B_matrix array:
B_matrix[] <- runif(length(B_matrix))

Java8: Reduce list of elements like sql group by

After a stream().filter().map() on a List I have a data structure of type List<List<Object>> that looks like this:
[["1","a",20],
["1","b",10],
["2","a",10],
["2","b",30]]
What I want is to group by the value of the first element of the inner list, leave the middle element out and finally sum the last elements for each "group".
[["1", 30],
["2", 40]]
Sorry if this is obvious for some of you, but I have yet to find any example of how to achieve this. I assumed it could be done by Stream.reduce(U identity, BiFunction accumulator, BinaryOperator combiner) but so far I haven't succeeded. If someone could provide some example code for this, I believe it would be appreciated by many others too.
The following code may be of help:
List<List<Object>> originalList = Arrays.asList(
Arrays.asList("1", "a", 20),
Arrays.asList("1", "b", 10),
Arrays.asList("2", "a", 10),
Arrays.asList("2", "b", 30)
);
final Map<Object, Integer> collectedMap =
originalList.stream()
.collect(Collectors.groupingBy(
e -> e.get(0),
Collectors.summingInt(e -> (Integer) e.get(2))));
System.out.println(collectedMap);
The output is:
{1=30, 2=40}
Basically, what the code does is to group by the first value in the sublist (get(0)). Then it sums the integers by the use of summingInt. However, it groups the entire thing in a Map - if some other collection is required the stream must be slightly changed.
E.g. to collect the whole thing as a List:
final List<List<Object>> collectedList =
collectedMap.entrySet()
.stream()
.map(e -> Arrays.asList(e.getKey(), e.getValue()))
.collect(Collectors.toList());
System.out.println(collectedList);
Then, the output will be:
[[1, 30], [2, 40]]

Resources