The groovy script needs to find the x location of string1 and put them into a list. The final output will be like
finaList=[[2,3],[5]]
The following scripts are created by me, but it doesn't work
checkStr='01xx0x1'
i=0
tempaList=[]
finalList=[]
while (i<checkStr.length()){
if(checkStr[i]=='x'){
tempaList.add(i)
}else if(tempaList.length()>1){
finalList.add([tempaList[0],tempaList[-1]])
tempaList=[]
}else if (tempaList.length()==1){
finaList.add([tempaList])
tempaList=[]
}
i=i+1
}
println finaList
I'm a bit confused by your desired result of a list of lists. If, as you stated, your only goal is to find all indexes that 'x' is at, you can use:
def str ='01xx0x'
str.findIndexValues { it == 'x' } // result -> [2, 3, 5]
If you do want to maintain your groupings, you need to make sure you handle the case of your last character being an 'x'. Your current code will not handle instances where tempaList has a value but the loop has finished iterating over the string.
def checkStr = '01xx0x1'
def temp = []
def end = []
for (int i=0; i < checkStr.size(); i++) {
if (checkStr[i] == 'x') {
temp << i
} else if (temp.size()) {
// temp has size (indexes) and we've hit a non-'x' char
end << temp
temp = []
}
}
// If the final char was an x (or multiple x's), handle that here
if (temp) {
end << temp
}
println end // result -> [[2, 3], [5]]
checkStr='01xx0x1'
i=0
tempaList=[]
finalList=[]
while(i<checkStr.length()){
if(checkStr[i]=="x"){
// println i
tempaList.add(i)
}else if (tempaList.size()>1){
finalList.add([tempaList[0],tempaList[-1]])
tempaList=[]
}else if (tempaList.size()==1){
finalList.add(tempaList)
tempaList=[]
}
i=i+1
}
println finalList
Related
Is there more Groovish way of adding an element to map of lists and initialize default list if not exists?
Or in other words what would be a Groovish way to code the below:
def mylist = [1,2,3,4]
def mymap = [:]
for (num in mylist){
if (num % 2 == 0){
pairity = "even"
} else {
pairity = "odd"
}
if (mymap.containsKey(pairity)){
println("Adding to Even")
mymap[pairity].add(num)
}
else {
println("adding to Odd")
mymap[pairity] = [num]
}
}
print(mymap.toString())
// adding to Odd
// adding to Odd
// Adding to Even
// Adding to Even
// [odd:[1, 3], even:[2, 4]]
You can use withDefault on a map to have automatically generate a value for a missing key on access.
[1,2,3,4].inject([:].withDefault{[]}){ m, i -> m[ i%2==0 ? 'odd' : 'even' ] << i; m }
// => [even:[1, 3], odd:[2, 4]]
You can simply groupby:
def mymap = mylist.groupBy { it % 2 == 0 ? 'even' : 'odd' }
That is effectively using the closure to partition the list on the condition.
I am new to groovy and trying to find the indexes of all sublists in a list.
I am trying to use something like Collections.indexOfSubList like in java but it gives exception saying it applies on Lists and not ArrayLists.
So I am trying to define my own function. I am finding all the indices of all the elements in the smaller list existing in the longer list and then subtracting the indices of the result array. If it comes to 1 then I am considering that index to a sublist.
I know that I have the logic a little twisted. Can somebody guide with a better and efficient way of doing this.
Below is my code:
List list1 = [1,2,3,4,5,6,1,2,3]
List list2 = [1,2]
index1 = list1.findIndexValues {
it == list2[0];
}
index2 = list1.findIndexValues {
it == list2[1];
}
println index1
println index2
result = []
for (int i = 0; i < index1.size(); i++) {
result.add(index2[i]-index1[i]);
}
println result
Edit: no longer uses Collections due to new issue re: Elastic Search.
The following code traverses along the source list, creating a sublist. It checks the sublist to see if it starts with the target list. See the asserts below (e.g. the indexes are 0-based):
def listStartsWithSubList = { source, target ->
def result = false
if (source.size() >= target.size()) {
result = true
target.eachWithIndex { item, index ->
result = result && (item == source[index])
}
}
result
}
def indexOfSubLists = { source, target ->
def results = []
source.eachWithIndex { item, index ->
def tmpList = source[index..source.size()-1]
if (listStartsWithSubList(tmpList, target)) {
results << index
}
}
results
}
assert [1] == indexOfSubLists([1,2,3], [2,3])
assert [2] == indexOfSubLists([1,2,3], [3])
assert [] == indexOfSubLists([1,2,3], [4])
assert [0,6] == indexOfSubLists([1,2,3,4,5,6,1,2,3], [1,2])
I've been trying to find a neat way to remove all but the last element from a list in groovy, but all the things I've tried seem a bit overcomplicated. Is there a neater way?
FAILS: java.util.ConcurrentModificationException
void removeAllButLastInPlace(list) {
if(list.size() > 1) {
def remove = list[0..-2]
remove.each { list.remove(it) }
}
}
FAILS: java.lang.CloneNotSupportedException: java.util.ArrayList$SubList
void removeAllButLastInPlace(list) {
if(list.size() > 1) {
def remove = list[0..-2].clone()
remove.each { list.remove(it) }
}
}
WORKS, but list construction seems unnecessary
void removeAllButLastInPlace(list) {
if(list.size() > 1) {
def remove = [] + list[0..-2]
remove.each { list.remove(it) }
}
}
WORKS, but seems a bit arcane
void removeAllButLastInPlace(list) {
(list.size() - 1).times { list.remove(0) }
}
WORKS, perhaps most 'correct'
void removeAllButLastInPlace(list) {
list.retainAll { list.lastIndexOf(it) == list.size() - 1 }
}
The code should fulfil the following tests:
list = []
removeAllButLastInPlace(list)
assert list == []
list = ['a']
removeAllButLastInPlace(list)
assert list == ['a']
list = ['a', 'b']
removeAllButLastInPlace(list)
assert list == ['b']
list = ['a', 'b', 'c']
removeAllButLastInPlace(list)
assert list == ['c']
Rather than mutating an existing list., why not return a new list?
Then you can simply do:
List removeAllButLast( List list ) {
list ? [list[-1]] : []
}
Or:
List removeAllButLastInPlace( List list ) {
list.drop( list.size() - 1 )
}
edit:
You could also use a loop (if you have to have a mutating method)
void removeAllButLastInPlace( List list ) {
while( list.size() > 1 ) list.remove( 0 )
}
void removeAllButLastInPlace( List list ) {
def index = 0
list.reverse(true).retainAll({index++ == 0})
}
I'd go for one of these. My criteria being a) modifying the list in place as stated in your requirement (not returning a new list) and b) succinctness.
I have however made both versions return a reference to the modified list just to simplify the println examples. You could make the return type 'void' if preferred and remove the last 'xs' line from each.
def xs1 = [1, 2, 3, 4, 5]
def xs2 = [9]
def xs3 = []
def keepOnlyLast1(xs) {
while(xs.size() > 1) xs.remove(0)
xs
}
def keepOnlyLast2(xs) {
xs[0 ..< xs.size()-1] = []
xs
}
println "Version 1"
println keepOnlyLast1([] + xs1)
println keepOnlyLast1([] + xs2)
println keepOnlyLast1([] + xs3)
println "Version 2"
println keepOnlyLast2([] + xs1)
println keepOnlyLast2([] + xs2)
println keepOnlyLast2([] + xs3)
/* Sanity check that these methods *really* modify the list. */
println "Sanity Check"
keepOnlyLast1(xs1)
println xs1
keepOnlyLast2(xs2)
println xs2
Aside: I would also go for a more functional style if at all possible (i.e. return a new list rather than modifying the existing one) except that that wasn't what you asked for. Here's an example anyway:
def lastAsList(xs) {
xs.isEmpty() ? [] : [xs[-1]]
}
println lastAsList([1, 2, 3])
println lastAsList([])
Lets say I have a string like this :
string = [+++[>>[--]]]abced
Now I want a someway to return a list that has: [[--],[>>],[+++]]. That is the contents of the deepest [ nesting followed by other nesting. I came up with this solution like this :
def string = "[+++[>>[--]]]"
loop = []
temp = []
string.each {
bool = false
if(it == "["){
temp = []
bool = true
}
else if( it != "]")
temp << it
if(bool)
loop << temp
}
println loop.reverse()
But this indeed takes the abced string after the last ] and put into the result!. But what I want is only [[--],[>>],[+++]]
Are there any groovy way of solving this?
You can use this, if you wouldn't mind using recursion
def sub(s , list){
if(!s.contains('[') && !s.contains('['))
return list
def clipped = s.substring(s.lastIndexOf('[')+1, s.indexOf(']'))
list.add(clipped)
s = s - "[$clipped]"
sub(s , list)
}
Calling
sub('''[+++[>>[--]]]abced''' , [])
returns a list of all subportions enclosed between braces.
['--', '>>', '+++']
If your brackets are symmetrical, you could just introduce a counter variable that holds the depth of the bracket nesting. Only depth levels above 0 are allowed in the output:
def string = "[+++[>>[--]]]abc"
loop = []
temp = []
depth = 0;
string.each {
bool = false
if(it == "["){
temp = []
bool = true
depth++;
}
else if (it == "]"){
depth--;
}
else if (depth > 0){
temp << it
}
if(bool){
loop << temp
}
}
println loop.reverse()
class Main {
private static final def pattern = ~/([^\[]*)\[(.+?)\][^\]]*/
static void main(String[] args) {
def string = "[+++[>>[--]]]abced"
def result = match(string)
println result
}
static def match(String val) {
def matcher = pattern.matcher(val);
if (matcher.matches()) {
return matcher.group(1) ? match(matcher.group(2)) + matcher.group(1) : match(matcher.group(2))
}
[val]
}
}
System.out
[--, >>, +++]
The capturing of the first group in the regex pattern could probably be improved. Right now the first group is any character that is not [ and if there are nothing in front of the first [ then the first group will contain an empty string.
I have a recursive Python function that builds a tree, and I'm trying to translate it into Groovy.
Here's the Python version...
def get_tree(vertices):
results = []
if type(vertices) != list:
vertices = [vertices]
for vertex in vertices:
results.append(vertex)
children = get_children(vertex)
if children:
child_tree = get_tree(children)
results.append(child_tree)
return results
Here's the output of get_tree(1)...
[1, [2, 3, 4, [5, 3]]]
And here's my attempt to translate this into a Groovy closure...
_tree = { vertices ->
results = []
vertices.each() {
results << it
children = it."$direction"().toList()
if (children) {
child_tree = _tree(children)
results << child_tree
}
}
results
}
But this doesn't work -- this is what it returns...
gremlin> g.v(1).outTree()
==>[v[5], v[3], (this Collection), (this Collection)]
What are those "this Collection"s about?
I have only a cursory understanding of Groovy, and I suspect it's something to do with how Groovy handles recursion and closure scope.
Please enlighten me :)
The solution was to add def to results = []:
_tree = { vertices ->
def results = []
vertices.each() {
results << it
children = it."$direction"().toList()
if (children) {
child_tree = _tree(children)
results << child_tree
}
}
results
}
See https://groups.google.com/d/msg/gremlin-users/iCPUifiU_wk/mrUhsjOM2h0J