How to nested loop in Groovy and get desired final output - groovy

I want to get the desired output from the below logic. The output should be a key-value pair.
I'm looping the apiList and appending the apiList <value> to input details <key>. If input details contains v1, the key is appended as (success_api.tenantId.host.v1:http):
class azureConfig {
public static void main(String[] args){
String inputDetails = """version=v1 host=http port=80"""
def inputList = inputDetails.split("\\s")
def id= "tenantId"
def apiList = [{api = success_api}, {api = fail_api}]
def keyValue = ""
for(String item: inputList){
def path = item.split("=")
keyValue += id + "." + path[0] + "::" + path[1] + "\n"
}
println(keyValue)
}
}
Output should be:
success_api.tenantId.host.v1::http
success_api.tenantId.port.v1::80
fail_api.tenantId.host.v1::http
fail_api.tenantId.port.v1::80
I have got this ouput for above logic:
tenantId.version::v1
tenantId.host::http
tenantId.port::80

Related

How to Replace Middle String to Other character in Dart?

final email = 'abcdefghij#email.com';
final phoneNumber = '0123456789';
This email string convert to this patter like
Fox Example
email -> ab****j#email.com
phoneNumber -> (012)3****89
Please help using RegExp and 0ther technics are most welcome.
Try this way
void main() {
var result = 'nilesh.rathod#gmail.com'.replaceAll(new RegExp('(?<=.)[^#](?=[^#]*?[^#]#)'), '*');
print(result);
}
You can use the replaceRange method
final email = 'abcdefghij#email.com';
final phoneNumber = '0123456789';
final hiderPlaceholder = "****";
final censuredEmail = email.replaceRange(2, email.indexOf("#")-1, hiderPlaceholder);
final censuredPhoneNumber = "(" + phoneNumber.substring(0, 3) + ")" + phoneNumber.substring(3).replaceRange(1, phoneNumber.substring(3).length-2, hiderPlaceholder);
print (censuredEmail);
print (censuredPhoneNumber);
Or you can just go for the evergreen substring
final email = 'abcdefghij#email.com';
final phoneNumber = '0123456789';
final hiderPlaceholder = "****";
final censuredEmail = email.substring(0, 2) + hiderPlaceholder + email.substring(email.indexOf("#")-1);
final censuredPhoneNumber = "(" + phoneNumber.substring(0, 3) + ")" + phoneNumber.substring(3, 4) + hiderPlaceholder + phoneNumber.substring(phoneNumber.length-2);
print (censuredEmail);
print (censuredPhoneNumber);
P.s. obviously, add all the controls you want, e.g. for the length of the email/phone number

How to change variables with in a string into a Map

I have let's say 100 variables in a string , my requirement is to automatically create a Map out of the string:
String str = "$$test$$ $$test2$$ $$test$$ $$test3$$"
Expected Result:
["test":test, "test2":test2, "test3":test3];
EDIT (for dsharew)
This is the last version of my code
def list = queryText.findAll(/\$\$(.*?)\$\$/)
def map = [:]
list.each{
log.debug(it)
it = it.replace("\$\$", "")
log.debug(it)
map.putAt(it, it)
}
log.debug(list)
log.debug(map)
queryText = queryText.replaceAll(/\$\$(.*?)\$\$/) { k -> map[k[1]] ?: k[0] }
log.debug(queryText)
And the logs print the following result:
$$test$$
test
$$test2$$
test2
$$test$$
test
$$test3$$
test3
[$$test$$, $$test2$$, $$test$$, $$test3$$]
{test=test, test2=test2, test3=test3}
test test2 test test3
This should do what you want:
def queryText = "\$\$test\$\$ \$\$test2\$\$ \$\$test\$\$ \$\$test3\$\$"
toMap(queryText.findAll(/\$\$(.*?)\$\$/));
def toMap(list){
def map = [:]
list.each{
it = it.replace("\$\$", "")
map.putAt(it, it)
};
println map;
return map;
}
Following #dsharew answer, I've reduced it a little bit more:
​def queryText = "\$\$test\$\$ \$\$test2\$\$ \$\$test\$\$ \$\$test3\$\$"
def resultMap = queryText
.findAll(/\$\$(.*?)\$\$/)
.collectEntries { String next ->
[next.replace("\$\$", "")] * 2
}
collectEntries can be used to return a map from a collection if it returns a map or a tuple for every entry in the collection.
If you multiply a list by n, you are creating a bigger list with n times its content
BTW cool problem!
This is what I came up with
String str = '$$test$$ $$test2$$ $$test$$ $$test3$$'
str.replaceAll('\\$\\$', '').split(' ').collectEntries { [(it):it] }

groovy map operation not giving expected value

I am trying to find duplicate tags in an xml file. and i wrote the following:
def xml = new XmlSlurper(false,false).parse('myfile.xml')
List<String> intNames = xml.depthFirst().findAll {
it.name() == 'InternalName'
}
println "Total:" + intNames.size()
// println "Unique:" + intNames.unique().size()
def map = [:]
for(itm in intNames){
if(map.get(itm) == null)
map.put(itm, 1)
else{
def val = map.get(itm)
map.put(itm, val + 1)
println itm
}
}
println "map size: ${map.size()}"
The result shows as:
Total:13811
map size: 13811
if i uncomment the line
// println "Unique:" + intNames.unique().size()
then it looks like
Total:13811
Unique:13792
map size: 13792
So, if unique has less number of values then why else clause is not able to print anything?

How to count letters, digits, spaces in a string

I'm working on a code to count the amount of spaces/digits/letters inside a given input using a loop. I am trying to use the .isdigit() and .isalpha() method to see if each letter in the string is a letter or number, and if true, adding it to the count. My code looks perfect to me, but when I run it, I only get the count for length and spaces (Which is not using the .isspace() method)
Perhaps I am messing up when updating the count within my loop but again.. it all looks good to me, could anyone help steer me in the right direction?
def main():
sentence = input('Enter a sentence: ')
printStats(sentence)
def printStats(input):
print('Statistics on your sentence: ')
print(' Characters:', charCount(input))
print(' Letters:', letterCount(input))
print(' Digits:', digitCount(input))
print(' Spaces:', spaceCount(input))
def charCount(input):
for char in input:
return len(input)
#Section below is where I need help
def letterCount(input):
count=0
for letter in input:
if input.isalpha():
count += 1
return count
def digitCount(input):
count=0
for digit in input:
if input.isdigit():
count += 1
return count
#Section above is where I need help
def spaceCount(input):
for space in input:
return input.count(" ")
main()
Thanks for your time
package com.drools;
public class TEST {
public static void main(String[] args) {
int charCount = 0;
int digitCount = 0;
String word = "NEW YORK 1";
String data[];
int k = 0;
data = word.split("");
int data1 = word.length();
char temp;
for (int i1 = 0; i1 < word.length(); i1++) {
temp = word.charAt(i1);
if (Character.isLetter(temp)) {
charCount++;
} else if (Character.isDigit(temp)) {
digitCount++;
for (int i = 0; i < data.length; i++) {
if (data[i].equals(" ")) {
k++;
}
}
System.out.println("total count "+ data1 + "||number of spaces in the entire word "+ k + " ||characters " + charCount+ " || digits" + digitCount);
}
}}
}
**Out put:**
total count 10||number of spaces in the entire word 2 ||characters 7 || digits1
You need to do letter.isalpha() and digit.isdigit() instead of calling them on the entire input.
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class LettersDigitsSpace {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Pattern pletter = Pattern.compile("[a-zA-Z]");
Pattern pdigit = Pattern.compile("\\d");
Pattern pwhitespace = Pattern.compile("\\s");
System.out.println();
System.out.println("-------------------------------------------------");
System.out.println("--- Letters, Digits, and White Spaces counter ---");
System.out.println("-------------------------------------------------");
System.out.println();
System.out.println("Enter String: ");
String val = input.nextLine();
Matcher mletter = pletter.matcher(val);
Matcher mdigit = pdigit.matcher(val);
Matcher mspace = pwhitespace.matcher(val);
int countl = 0, countd = 0, counts = 0;
while (mletter.find()) {
countl++;
}
while (mdigit.find()) {
countd++;
}
while (mspace.find()) {
counts++;
}
System.out.println("\nLetter count: "+countl+"\nDigit count: " + countd + "\nWhite Space count: " + counts);
}
}

How I can find the contents of inner nesting?

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.

Resources