Extracting last item from string in foreach loop - foreach

I'm working on matrix that contains the name of a class, but sometimes the class name is very long and I only need two last sections of name.
I have string containing some text, separated with '.', and I need to extract last two text.
For example:
string : af.bf.cf.df.ef
my needed value : df.ef
I wrote some code, but it's not working:
string[] split1 = "af.bf.cf.df.ef";
foreach (string item in split1)
{
string myvalue = item;
}

string[] list = "1.2.3.4.5".Split('.');
string last2 = list[ list.count - 2] + "." + list[ list.count - 1];

Related

Dart converting String to Array then compare two array

I'm trying to convert strings to arrays then compare two arrays. If the same value needs to remove from both array. Then finally merge two arrays and find array length. Below is my code
String first_name = "siva";
String second_name = "lovee";
List<String> firstnameArray=new List();
List<String> secondnameArray=new List();
firstnameArray = first_name.split('');
secondnameArray = second_name.split('');
var totalcount=0;
for (int i = 0; i < first_name.length; i++) {
for (int j = 0; j < second_name.length; j++) {
if (firstnameArray[i] == secondnameArray[j]) {
print(firstnameArray[i] + "" + " == " + secondnameArray[j]);
firstnameArray.removeAt(i);
secondnameArray.removeAt(i);
break;
}
}
}
var finalList = new List.from(firstnameArray)..addAll(secondnameArray);
print(finalList);
print(finalList.length);
But always getting this error Unsupported operation: Cannot remove from a fixed-length list can you help me how to fix this issue. Thanks.
Seems like what you are trying to do is to find the length of unique characters in given two strings. Well, the Set type is perfect for this use-case. Here's an example of what you can do:
void main() {
String first = 'abigail';
String second = 'allie';
var unique = '$first$second'.split('').toSet();
print(unique);
}
This would give you an output of:
{a, b, i, g, l, e}
On which you may perform functions like .toList(), or .where() or .length.
You can ensure that firstnameArray, secondnameArray is not a fixed-length list by initializing it as below:
var firstnameArray = new List<String>.from(first_name.split(''));
var secondnameArray= new List<String>.from(second_name.split(''));
Thereby declaring firstnameArray, secondnameArray to be a mutable copy of input.

Flutter/Dart: Split string by first occurrence

Is there a way to split a string by some symbol but only at first occurrence?
Example: date: '2019:04:01' should be split into date and '2019:04:01'
It could also look like this date:'2019:04:01' or this date : '2019:04:01' and should still be split into date and '2019:04:01'
string.split(':');
I tried using the split() method. But it doesn't have a limit attribute or something like that.
You were never going to be able to do all of that, including trimming whitespace, with the split command. You will have to do it yourself. Here's one way:
String s = "date : '2019:04:01'";
int idx = s.indexOf(":");
List parts = [s.substring(0,idx).trim(), s.substring(idx+1).trim()];
You can split the string, skip the first item of the list created and re-join them to a string.
In your case it would be something like:
var str = "date: '2019:04:01'";
var parts = str.split(':');
var prefix = parts[0].trim(); // prefix: "date"
var date = parts.sublist(1).join(':').trim(); // date: "'2019:04:01'"
The trim methods remove any unneccessary whitespaces around the first colon.
Just use the split method on the string. It accepts a delimiter/separator/pattern to split the text by. It returns a list of values separated by the provided delimiter/separator/pattern.
Usage:
const str = 'date: 2019:04:01';
final values = string.split(': '); // Notice the whitespace after colon
Output:
Inspired by python, I've wrote this utility function to support string split with an optionally maximum number of splits. Usage:
split("a=b=c", "="); // ["a", "b", "c"]
split("a=b=c", "=", max: 1); // ["a", "b=c"]
split("",""); // [""] (edge case where separator is empty)
split("a=", "="); // ["a", ""]
split("=", "="); // ["", ""]
split("date: '2019:04:01'", ":", max: 1) // ["date", " '2019:04:01'"] (as asked in question)
Define this function in your code:
List<String> split(String string, String separator, {int max = 0}) {
var result = List<String>();
if (separator.isEmpty) {
result.add(string);
return result;
}
while (true) {
var index = string.indexOf(separator, 0);
if (index == -1 || (max > 0 && result.length >= max)) {
result.add(string);
break;
}
result.add(string.substring(0, index));
string = string.substring(index + separator.length);
}
return result;
}
Online demo: https://dartpad.dev/e9a5a8a5ff803092c76a26d6721bfaf4
I found that very simple by removing the first item and "join" the rest of the List
String date = "date:'2019:04:01'";
List<String> dateParts = date.split(":");
List<String> wantedParts = [dateParts.removeAt(0),dateParts.join(":")];
Use RegExp
string.split(RegExp(r":\s*(?=')"));
Note the use of a raw string (a string prefixed with r)
\s* matches zero or more whitespace character
(?=') matches ' without including itself
You can use extensions and use this one for separating text for the RichText/TextSpan use cases:
extension StringExtension on String {
List<String> controlledSplit(
String separator, {
int max = 1,
bool includeSeparator = false,
}) {
String string = this;
List<String> result = [];
if (separator.isEmpty) {
result.add(string);
return result;
}
while (true) {
var index = string.indexOf(separator, 0);
print(index);
if (index == -1 || (max > 0 && result.length >= max)) {
result.add(string);
break;
}
result.add(string.substring(0, index));
if (includeSeparator) {
result.add(separator);
}
string = string.substring(index + separator.length);
}
return result;
}
}
Then you can just reference this as a method for any string through that extension:
void main() {
String mainString = 'Here was john and john was here';
print(mainString.controlledSplit('john', max:1, includeSeparator:true));
}
Just convert list to string and search
productModel.tagsList.toString().contains(filterText.toLowerCase())

Accessing jsonpath elements with nested objects

I am looking to extract certain values from a JSON path of arrays and objects and use these values for further processing and am struggling with accessing those elements. Here is the JSON response:
[
{
"od_pair":"7015400:8727100",
"buckets":[
{
"bucket":"C00",
"original":2,
"available":2
},
{
"bucket":"A01",
"original":76,
"available":0
},
{
"bucket":"B01",
"original":672,
"available":480
}
]
},
{
"od_pair":"7015400:8814001",
"buckets":[
{
"bucket":"C00",
"original":2,
"available":2
},
{
"bucket":"A01",
"original":40,
"available":40
},
{
"bucket":"B01",
"original":672,
"available":672
},
{
"bucket":"B03",
"original":632,
"available":632
},
{
"bucket":"B05",
"original":558,
"available":558
}
]
}
]
I tried accessing the root elements with $ but I could not get further with it.
Here is the test method that I have written. I want to extract the value for od_pair and within each od_pair, I need to be able to retrieve the bucket codes and their available numbers.
public static void updateBuckets(String ServiceName, String DateOfJourney) throws Exception {
File jsonExample = new File(System.getProperty("user.dir"), "\\LogAvResponse\\LogAvResponse.json");
JsonPath jsonPath = new JsonPath(jsonExample);
List<Object> LegList = jsonPath.getList("$");
// List<HashMap<String, String>> jsonObjectsInArray = jsonPath.getList("$");
int NoofLegs = LegList.size();
System.out.println("No of legs :" + NoofLegs);
for (int j = 0; j <= NoofLegs; j++)
// for (HashMap<String, String> jsonObject : jsonObjectsInArray) {
{
String OD_Pair = jsonPath.param("j", j).getString("[j].od_pair");
// String OD_Pair = jsonObject.get("od_pair");
System.out.println("OD Pair: " + OD_Pair);
List<Object> BucketsList = jsonPath.param("j", j).getList("[j].buckets");
int NoOfBuckets = BucketsList.size();
// System.out.println("OD Pair: " + OD_Pair);
System.out.println("no of Buckets: " + NoOfBuckets);
for (int i = 0; i < NoOfBuckets; i++) {
String BucketCode = jsonPath.param("j", j).param("i", i).getString("[j].buckets[i].bucket");
String Available = jsonPath.param("j", j).param("i", i).getString("[j].buckets[i].available");
int BucketCodeColumn = XLUtils.getBucketCodeColumn(BucketCode);
int ServiceRow = XLUtils.getServiceRow(ServiceName, DateOfJourney, OD_Pair);
System.out.println("Row of " + ServiceName + ":" + DateOfJourney + "is:" + ServiceRow);
System.out.println("Bucket Code column of " + BucketCode + " is: " + BucketCodeColumn);
XLUtils.updateAvailability(ServiceRow, BucketCodeColumn, Available);
}
}
}
}
This is the error I see:
Caused by:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup
failed:
Script1.groovy: 1: unexpected token: [ # line 1, column 27.
restAssuredJsonRootObject.[j].od_pair
Can someone help me please?
I would suggest parsing your JSON into Java classes to ease the processing.
How to do that?
First, we need to create Java classes which will represent the JSON you provided.
Let's analyze the JSON.
Starts with an array. The array contains multiple JSON Object. These objects contain od_pair value and array of objects called buckets.
Let's create a class (you can name it whatever you want) Pair
public class Pair {
public String od_pair; //this name is important because it corresponds with the json element's name!
public List<BucketObject> buckets; //same here!
}
This class represents a single JSON Object in the main Array. It contains od_pair value AND nested JSON Array but in Java representation -> List of BucketObject classes. Let's create BucketObject class:
public class BucketObject { //this name is NOT importnat
public String bucket; //names are important
public int original;
public int available;
}
We have only 3 values in each of the objects.
Now, it's time to parse JSON into the written classes.
JsonPath path = JsonPath.from(json);
Pair[] pairs = path.getObject("$", Pair[].class);
Remember that Pair is a single JSON Object. That's why we start parsing from the root represented by dollar sign $ and we declare that JSON should be parsed into an ARRAY of Pair objects!
Now, processing will be much simpler!
I am not sure what do you need, but I will show you an example of how to get data from the buckets based on od_pair field and you should be able to figure out the rest of the processing.
So, we have the array of Pair class: Pair[] pairs;
Now, we want to get 1 Pair object based on od_pair value.
public static Pair getPairBasedOnOdPairValue(Pair[] pairs, String odPairValue) {
for (Pair pair : pairs) {
if (pair.od_pair.equals(odPairValue)) return pair;
}
throw new NoSuchElementException();
}
Now, we have the Pair object. We can access buckets for this object using
List<BucketObject> buckets = pair.buckets;
The rest of the processing is iterating over List<BucketObject> and getting desired values.
Hope it helps!
OP asked me to advise on how to fix his code, hence the second answer.
Let's analyze the code you provided:
public static void updateBuckets(String ServiceName, String DateOfJourney) throws Exception {
File jsonExample = new File(System.getProperty("user.dir"), "\\LogAvResponse\\LogAvResponse.json");
JsonPath jsonPath = new JsonPath(jsonExample);
List<Object> LegList = jsonPath.getList("$");
// List<HashMap<String, String>> jsonObjectsInArray = jsonPath.getList("$");
int NoofLegs = LegList.size();
System.out.println("No of legs :" + NoofLegs);
for (int j = 0; j <= NoofLegs; j++)
// for (HashMap<String, String> jsonObject : jsonObjectsInArray) {
{
String OD_Pair = jsonPath.param("j", j).getString("[j].od_pair");
// String OD_Pair = jsonObject.get("od_pair");
System.out.println("OD Pair: " + OD_Pair);
List<Object> BucketsList = jsonPath.param("j", j).getList("[j].buckets");
int NoOfBuckets = BucketsList.size();
// System.out.println("OD Pair: " + OD_Pair);
System.out.println("no of Buckets: " + NoOfBuckets);
for (int i = 0; i < NoOfBuckets; i++) {
String BucketCode = jsonPath.param("j", j).param("i", i).getString("[j].buckets[i].bucket");
String Available = jsonPath.param("j", j).param("i", i).getString("[j].buckets[i].available");
int BucketCodeColumn = XLUtils.getBucketCodeColumn(BucketCode);
int ServiceRow = XLUtils.getServiceRow(ServiceName, DateOfJourney, OD_Pair);
System.out.println("Row of " + ServiceName + ":" + DateOfJourney + "is:" + ServiceRow);
System.out.println("Bucket Code column of " + BucketCode + " is: " + BucketCodeColumn);
XLUtils.updateAvailability(ServiceRow, BucketCodeColumn, Available);
}
}
}
I am not using compilator right now, so I can miss a few things.
#1
First thing I can see is that you save the main array into the List<Object>
List<Object> LegList = jsonPath.getList("$");
Instead, you could save it to more understandable type, since Object is so generic, you have no idea what's inside it.
List<HashMap<String, Object>> LegList = jsonPath.getList("$");
#2
The for loop looks incorrect because of the evaluator
j <= NoofLegs;.
This will probably cause IndexArrayOutOfBoundsException or something similar. With the given code, if you have 4 legs, the for loop will try to process 5 legs which are incorrect.
#3
Similar to the #1, line where you save the bucket list
List<Object> BucketsList = jsonPath.param("j", j).getList("[j].buckets");
Could also be changed to List<HashMap<String, Object>> instead.
If you'd do that, you wouldn't need integer-based nested for loop.
You see, the HashMap<String, Object> is actually crucial to parse nested objects. The String is just a name like buckets or od_pair. It's the JSON representation. The second argument Object is different. RestAssured returns different types within the HashMap, that's why we use Object instead of String. Sometimes it's not String.
Example based on your JSON:
Collect buckets to List of HashMaps:
List<HashMap<String, Object>> bucketsList = jsonPath.param("j", j).getList("[j].buckets");
Each of the HashMap in the list is a representation of this:
{
"bucket":"C00",
"original":2,
"available":2
},
The Object in HashMap is either String or Integer in your case.
So, if you get element bucket from a HashMap you'll get its value.
Let's combine it with for loop for further clarification:
List<HashMap<String, Object>> bucketsList = jsonPath.param("j", j).getList("[j].buckets");
for (HashMap<String, Object> singleBucket : bucketsList) {
String firstValue = (String) singleBucket.get("bucket");
Integer secondValue = (Integer) singleBucket.get("original");
}
Looking at the error message, it looks like you are using rest-assured and that the JsonPath class is io.restassured.path.json.JsonPath from the rest-assured library.
I'm sure you're aware, but (perhaps for other readers) note that this is different from Jayway's json-path and is NOT the com.jayway.jsonpath.JsonPath class from that library.
Also be aware that, as mentioned in the documentation rest-assured uses the Groovy GPath syntax for manipulating/extracting JSON.
With that, I believe the following will extract what you need, i.e. od_pair and their corresponding buckets with available numbers:
Map<String, Map<String, Integer>> map = JsonPath.with(jsonString).get("collectEntries{entry -> [entry.od_pair, entry.buckets.collectEntries{bucketEntry -> [bucketEntry.bucket, bucketEntry.available]}]}");
where for each entry of the map, the key is the od_pair and the value is another map whose key is the bucket and value is the available number. The jsonString is the JSON you provided in the question.
You can iterate through the map to get what you want:
for(Map.Entry<String, Map<String, Integer>> entry : map.entrySet())
{
String od_pair = entry.getKey();
Map<String, Integer> bucketMap = entry.getValue();
for(Map.Entry<String, Integer> bucketEntry : bucketMap.entrySet())
{
String bucket = bucketEntry.getKey();
int available = bucketEntry.getValue();
}
}
Printing out the map you will get:
{7015400:8727100={C00=2, A01=0, B01=480}, 7015400:8814001={C00=2, A01=40, B01=672, B03=632, B05=558}}
Printing the map as JSON using Gson:
System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(map));
you will get
{
"7015400:8727100": {
"C00": 2,
"A01": 0,
"B01": 480
},
"7015400:8814001": {
"C00": 2,
"A01": 40,
"B01": 672,
"B03": 632,
"B05": 558
}
}
For background, the String collectEntries{entry -> [entry.od_pair, entry.buckets.collectEntries{bucketEntry -> [bucketEntry.bucket, bucketEntry.available]}]}
is a Groovy closure that uses methods from the Groovy Collections API: Refer Collection, List and Map
Shout out to #Fenio for the pure Java solution above.

How can I insert a space character in every upper case letter expect the first one at each element of string array in DXL script?

I would like to edit the elements of string array with DXL script which is used in for loop. The problem will be described in the following:
I would like to insert space in front of every upper case letter expect the first one and it would be applied for all lines in string array.
Example:
There is a string array:
AbcDefGhi
GhiDefAbc
DefGhiAbc
etc.
and finally I would like to see the result as:
Abc Def Ghi
Ghi Def Abc
Def Ghi Abc
etc.
Thanks in advance!
Derived straightly from the DXL manual..
Regexp upperChar = regexp2 "[A-Z]"
string s = "yoHelloUrban"
string sNew = ""
while (upperChar s) {
sNew = sNew s[ 0 : (start 0) - 1] " " s [match 0]
s = s[end 0 + 1:]
}
sNew = sNew s
print sNew
You might have to tweak around the fact that you do not want EVERY capital letter to be replaced with , only those that are not at the beginning of your string.
Here's a solution written as a function that you can just drop into your code. It processes an input string character by character. Always outputs the first character as-is, then inserts a space before any subsequent upper-case character.
For efficiency, if processing a large number of strings, or very large strings (or both!), the function could be modified to append to a buffer instead of a string, before finally returning a string.
string spaceOut(string sInput)
{
const int intA = 65 // DECIMAL 65 = ASCII 'A'
const int intZ = 90 // DECIMAL 90 = ASCII 'Z'
int intStrLength = length(sInput)
int iCharCounter = 0
string sReturn = ""
sReturn = sReturn sInput[0] ""
for (iCharCounter = 1; iCharCounter < intStrLength; iCharCounter++)
{
if ((intOf(sInput[iCharCounter]) >= intA)&&(intOf(sInput[iCharCounter]) <= intZ))
{
sReturn = sReturn " " sInput[iCharCounter] ""
}
else
{
sReturn = sReturn sInput[iCharCounter] ""
}
}
return(sReturn)
}
print(spaceOut("AbcDefGHi"))

Extract More than 3 Words After the First Word

In the app I'm working on, I need to extract the first word from a String and put it into another String and the rest of the words in yet another String. I was able to extract the first word using:
String pString = "KOF0000094 Implementation:ListingRequest:User FO-Partner"
int spacePos3 = pString.indexOf(" ");
String pFirstWord = pString.substring(0,spacePos3);
Result : KOF0000094
Now I want the "Implementation:ListingRequest:User FO-Partner" to put
in another String.
Thanks for your help in advance
Simplest solution with what you already have.
String restOfString = pString.substring(spacePos3+1)
String pSecondWord = pString.substring(spacePos3 + 1);
String whole = "KOF0000094 Implementation:ListingRequest:User FO-Partner";
String firstWord = "";
String restOfWords = "";
int spacesIndex = whole.indexOf(" ", 0);
restOfWords = whole.substring(spacesIndex, whole.length());
restOfWords = restOfWords.trim();
firstWord = whole.substring(0, spacesIndex);
firstWord = firstWord.trim();
This is simple string parsing... just find the first index of the first space... i.e. in a for loop...
if(string.charAt(i) == Characters.SPACE)
indexOfSpace = i;
Then your first word will be
String part1 = string.substring(0,indexOfSpace);
and the second string will be
String part2 = string.substring(indexOfSpace + 1);
Try using another call to substring(). What is the index of the first character in the string you want? What is the index of the last character?
You already have the index of the first space, which marks the end of the first word, so all you need to do is take the substring from the index immediately after that (so you don't include the space itself) to the end of the string.
You're probably better of using the split function
It would look something like this:
String pString = "KOF0000094 Implementation:ListingRequest:User FO-Partner";
String[] parts = pString.split(" ");
String partone = parts[0];
String partwo = parts[1] + " " +parts[2];
Or something similar, if there are going to be more spaces in the part following the first word you could use a loop or something similar;
You could use split, for instance...
static String pString = "KOF0000094 Implementation:ListingRequest:User FO-Partner";
static String[] pFirstWord = pString.split(" ");
/**
* #param args
*/
public static void main(String[] args) {
for(String word : pFirstWord) {
System.out.println(word);
}
}
This returned...
KOF0000094
Implementation:ListingRequest:User
FO-Partner
So the last string would be pFirstWord[1] + pFirstWord[2]
String class has a split method: http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#split(java.lang.String)
Use that if you want to get all the words.
EDIT: as mentioned in the comments, String.split is not supported in BB Java.
Or this if you just want the first word and the rest of the string:
int index=yourstring.indexOf(" ");
String firstWord = yourstring.substring(0,index);
String rest = yourstring.substring(index+1);

Resources