Remove item from groovy list - collections

I am trying to remove an item from groovy list. I've tried following:
List<User> availableUsers = []
availableUsers = workers
for (int i = 0; i < availableUsers.size(); i++) {
if (availableUsers[i].equals(user)){
availableUsers.drop(i)
break
}
}
I've also tried:
availableUsers.remove(user)
In both cases the list gets emptied. Does anyone have any idea what's going on?

Have you tried
availableUsers - user
?
Docu: http://groovy.codehaus.org/groovy-jdk/java/util/List.html#minus(java.lang.Object)
Haven't got much experience with groovy myself, but that's what I would try.

As mentioned above, the answer depends on whether you wish to remove all occurrences of an item...
myList = ['a','b','c', 'c']
myList -= 'c'
assert myList == ['a','b']
...or just the first instance.
myList = ['a','b','c', 'c']
myList.remove(myList.indexOf('c'))
assert myList == ['a','b','c']
I'm still new to Groovy myself, but one of the underlying principles is that it almost always has a way of making common tasks trivial one-liners. Adding or removing items from a collection would certainly qualify.

Fildor is right, but if you only want ot remove the first occurence of user in your list (minus will remove all occurrences), you will probably need something like:
list = list.indexOf( user ).with { idx ->
if( idx > -1 ) {
new ArrayList( list ).with { a ->
a.remove( idx )
a
}
}
else list
}

I had a related requirement but wanted to remove more than one items knowing their index position. It was not easy to do in a loop as after removing the first item, the index position of the remaining ones changes. It seemed easy to first create a list with items to be removed and then use the collections minus operation to remove them from the target list. Here is an example:
myList=['a','b','c','d']
remove=[0,1,2] //index list of list elements to remove
removeList=myList[remove]
println removeList
assert ['d']== myList.minus(removeList)
LIMITATION:if the value at index is present multiple times in target list, ALL instances are removed.
So, if
myList=['a','b','c','d','a','e']
remove=[0,1,2]
removeList=myList[remove]
assert myList.minus(removeList)== ['d','e']
the result will be d,e

Related

Only able to access first record in a query

(server side script)
This is a stripped down version of my code but what this should be doing is
find records where the "uniqueid" is equal to matchid
return 0 if there are less than two of these items
print the region of each item if there are two or more items
return the number of items
function copyFile(matchid){
var fileName = getProp('projectName')+" "+row[0];
var query = app.models.Files.newQuery();
query.filters.uniqueid._equals = matchid;
records = query.run();
var len = records.length;
if (len < 2) return 0;
console.log(row[2]+" - "+len);
for (var i=0; i<len;i++){
console.log("Loop "+i);
var r = records[i];
console.log(r.region);
}
return records.length
Strangely, it can only get at the region (or any of the other data for the FIRST record ( records[0]) for the others it says undefined. This is extremely confusing and frustrating. To reiterate it passes the len < 2 check, so there are more records in the set returned from the query, they just seem to be undefined if I try to get them from records[i]
Note: uniqueid is not actually a unique field, the name is from something else, sorry about confusion.
Question: WHY can't I get at records[1] records [2]
This was a ridiculous problem and I don't entirely understand the solution.
Changing "records" to "recs" entirely fixes my problem.
why does records[0] work, records[1] does not
but recs[0] and recs[1] both work.
I believe "records" has a special meaning and points at something regardless of assignment in this context.

How to solve this error of conditional statements and Loops in R?

You can suggest me any sort of answers, not necessarily need using conditional statements and Loops.
I have the data set with several ids and and three alert or groups.
here is the image for the concept:
and here is the actual Data set for one ID: Click me
Concept is:
I have three alert: Relearn - Rebuild - Replace.
and after relearn: rebuild or replace can come but relearn cannot come
and after rebuild: replace can come but relearn cannot come
after replace: relearn and rebuild cannot come. if there is any replace only that can come
I have attached the image and Dataset for better clear understanding and Here is my try:
temp1 = NULL
temp2 = NULL
sql50 = NULL
for(i in 1:nrow(BrokenPins)) #First Loop
{
sql50 = sqldf(paste("select * from rule_data where key = '",BrokenPins[i,1],"'",sep = ""))
for(j in 1:nrow(sql50))
{ #Second Loop
while (head(sql50$Flag,1) == sql50$Flag[j] )
{
temp1 = sql50[j,]
temp2 = rbind(temp2,temp1)
print("Send")
if(j == 1 || sql50$Flag[j] == sql50$Flag[j-1])
{
j = j+1
}
else(sql50$Flag[j] > sql50$Flag[j-1])
{
break
}
}
}
}
First loop will go through each id and second loop will give me all the alert for that id.
so in the image i have added send and dont send. it wont be in actual table. that basically means send means copy it to new dataframe like i am doing above rbind in the code and dont send means dont copy it. This Above piece of code will run but only take the first and end it.
Finally, Based On above Data set Click me: that is for one ID (key), Flag (1 - Relearn, 2-Rebuild,3-replace). so based on this dataset. my output should have Row 1, 2 and 7 because First Relearn[Flag 1] came then Rebuild[Flag 2] then again relearn[Flag 1]cannot come, only rebuild [Flag 2] and replace[Flag 2] can.
can you help me solve this concept?
One thing I notice is that you use else and also provided a condition; you should only use else when you want every case that is not included in the condition of your if statement. Basically, instead of using else(sql50$Flag[j] > sql50$Flag[j-1]) you should be using else if(sql50$Flag[j] > sql50$Flag[j-1]).

R: Iterating Over the List

I am trying to implement following algorithm in R:
Iterate(Cell: top)
While (top != null)
Print top.Value
top = top.Next
End While
End Iterate
Basically, given a list, the algorithm should break as soon as it hits 'null' even when the list is not over.
myls<-list('africa','america south','asia','antarctica','australasia',NULL,'europe','america north')
I had to add a for loop for using is.null() function, but following code is disaster and I need your help to fix it.
Cell <- function(top) {
#This algorithm examines every cell in the linked list, so if the list contains N cells,
#it has run time O(N).
for (i in 1:length(top)){
while(is.null(top[[i]]) !=TRUE){
print(top)
top = next(top)
}
}
}
You may run this function using:
Cell(myls)
You were close but there is no need to use for(...) in this
construction.
Cell <- function(top){
i = 1
while(i <= length(top) && !is.null(top[[i]])){
print(top[[i]])
i = i + 1
}
}
As you see I've added one extra condition to the while loop: i <= length(top) this is to make sure you don't go beyond the length of the
list in case there no null items.
However you can use a for loop with this construction:
Cell <- function(top){
for(i in 1:length(top)){
if(is.null(top[[i]])) break
print(top[[i]])
}
}
Alternatively you can use this code without a for/while construction:
myls[1:(which(sapply(myls, is.null))[1]-1)]
Check this out: It runs one by one for all the values in myls and prints them but If it encounters NULL value it breaks.
for (val in myls) {
if (is.null(val)){
break
}
print(val)
}
Let me know in case of any query.

What is wrong with this code? why the List does not identify?

what is wrong with this code?
bool claimExists;
string currentClaimControlNo = "700209308399870";
List<string> claimControlNo = new List<string>();
claimControlNo.Add("700209308399870");
if (claimControlNo.Contains(currentClaimControlNo.Substring(0, 14)))
claimExists = true;
else
claimExists = false;
Why the claimControlNo above is coming into false?
Since I know the value exists, how can i tune the code?
It's reporting false because you aren't asking whether the list contains the currentClaimControlNo, you're asking whether it contains a string that is the first fourteen characters of the fifteen-character string currentClaimControlNo.
Try this instead:
claimExists = claimControlNo.Any(ccn => ccn.StartsWith(currentClaimControlNo.Substring(0,14)));
Your count is wrong. There are 15 characters. Your substring is cutting off the last 0 which fails the condition.
Because you're shaving off the last digit in your substring.
if you change the line
if (claimControlNo.Contains(currentClaimControlNo.Substring(0, 14)))
to
if (claimControlNo.Contains(currentClaimControlNo.Substring(0, 15)))
it works.
Because contains on a list looks for the whole item, not a substring:
currentClaimControlNo.Substring(0, 14)
"70020930839987"
Is not the same as
700209308399870
You're missing a digit, hence why your list search is failing.
I think you are trying to find something in the list that contains that substring. Don't use the lists contain method. If you are trying to find something in the list that has the subset do this
claimExists = claimControlNo.Any(item => item.Contains(currentClaimControlNo.Substring(0, 14)))
This goes through each item in claimControlNo and each item can then check if it contains the substring.
Why do it this way? The Contains method on a string
Returns a value indicating whether the specified System.String object occurs within this string.
Which is what you want.
Contains on a list, however
Determines whether an element is in the System.Collections.Generic.List.
They aren't the same, hence your confusion
Do you really need this explaining?
You are calling Substring for 14 characters when the string is of length 15. Then you are checking if your list (which only has one item of length 15) contains an item of length 14. It doesn;t event need to check the value, the length is enough to determine it is not a match.
The solution of course is to not do the Substring, it makes not sense.
Which would look like this:
if (claimControlNo.Contains(currentClaimControlNo))
claimExists = true;
else
claimExists = false;
Then again, perhaps you know you are trimming the search, and are in fact looking for anything that has a partial match within the list?
If this is the case, then you can simply loop the list and do a Contains on each item. Something like this:
bool claimExists = false;
string searchString = currentClaimControlNo.Substring(0, 14);
foreach(var s in claimControlNo)
{
if(s.Contains(searchString))
{
claimExists = true;
break;
}
}
Or use some slightly complex (certainly more complex then I can remember off the top of my head) LINQ query. Quick guess (it's probably right to be fair, I am pretty freaking awesome):
bool claimExists = claimControlNo.Any(x => x.Contains(searchString));
Check it:
// str will be equal to 70020930839987
var str = currentClaimControlNo.Substring(0, 14);
List<string> claimControlNo = new List<string>();
claimControlNo.Add("700209308399870");
The value str isn't contained in the list.

Accessing grid columns in same sequence in which they are visible

I need to access columns of infragistics ultragrid in same sequence in which they are being displayed in grid. If i can get the index of column in same sequence as they are visible on grid, i can fix my issues.
Thanks in advance.
Lalit
UltraGridColumn column = this.ultraGrid1.DisplayLayout.Bands[0].Columns[0];
Debug.WriteLine( "Columns in visible order: ");
// Get the first visible column by passing in VisibleRelation.First.
column = column.GetRelatedVisibleColumn( VisibleRelation.First );
while ( null != column )
{
Debug.WriteLine( " " + column.Key );
// Get the next visible column by passing in VisibleRelation.Next.
column = column.GetRelatedVisibleColumn( VisibleRelation.Next );
}
http://help.infragistics.com/Help/NetAdvantage/NET/2008.2/CLR2.0/html/Infragistics2.Win.UltraWinGrid.v8.2~Infragistics.Win.UltraWinGrid.UltraGridColumn~GetRelatedVisibleColumn.html
I suppose you could try to handle the event that is fired when the order is changed and keep track of all the changes, but this seems like it is asking for subtle bugs to creep in.
I considered looping through all the columns and trying to use some property that would tell me their current position (maybe the TabOrder?) and use that to compile an inorder list of the columns. I guess you might have to loop through each colum using the Column.GetRelatedVisibleColumn() method.
I have not actually implemented it yet as I have other higher priority issues but that may be the road I end up going down.
This is an old question, but I recently had same issue and solved it this way:
var selectedCells = this.Selected.Cells;
List<int> columns = new List<int>();
foreach (var cell in selectedCells)
{
if (!columns.Contains(cell.Column.Index))
columns.Add(cell.Column.Index);
}
columns.Sort((x, y) => this.DisplayLayout.Rows.Band.Columns[x].Header.VisiblePosition.CompareTo(this.DisplayLayout.Rows.Band.Columns[y].Header.VisiblePosition));
You can then use columns to access columns in order they are shown.

Resources