Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
In C# I am passing a single string value to a function. The value is similar to this: "XA=12345678;BK=AZ31" or "XA=87654321", sometimes the BK= is there, sometimes it is not. But if it's present, I need it for my function.
I've made this attempt:
string[] item_list = { "XA=12345678;BK=AZ31", "XA=87654321" };
string XA_EQ = "";
string BK_EQ = "";
foreach(string item in item_list)
{
BK_EQ = "";
string[] split = item.Split(';');
XA_EQ = split[0];
if(split.length == 2)
BK_EQ = split[1];
my_func(XA_EQ, BK_EQ);
}
Is there a better way to do this? This works, but it seems inconvenient.
RegEx approach
string[] item_list = { "XA=12345678;BK=AZ31", "XA=87654321" };
foreach (string item in item_list)
{
string XA_EQ = Regex.Match(item, "(?<=XA=)[0-9A-Z]*").Value;
string BK_EQ = Regex.Match(item, "(?<=BK=)[0-9A-Z]*").Value;
my_func(XA_EQ, BK_EQ);
}
https://dotnetfiddle.net/6xgBi3
I suggest Splitting initial strings into Dictionary:
using System.Linq;
...
private static Dictionary<string, string> GetVariables(string source) {
return source
.Split(';')
.Select(pair => pair.Split('='))
.ToDictionary(pair => pair[0].Trim(), pair => pair[1].Trim());
}
Now we can analyze values:
string[] item_list = new string[] { "XA=12345678;BK=AZ31", "XA=87654321" };
foreach(string item in item_list) {
var namesAndValues = GetVariables(item);
// If we have XA variable, assign its value to XA_EQ, otherwise assign ""
string XA_EQ = namesAndValues.TryGetValue("XA", out string xa) ? xa : "";
// If we have "BK" variable, call my_func with it
if (namesAndValues.TryGetValue("BK", out string BK_EQ)) {
// If we have "BK" variable
my_func(XA_EQ, BK_EQ);
}
}
Easy to read solution with LINQ:
string[] itemList = { "XA=12345678;BK=AZ31", "XA=87654321" };
itemList.Select(x => x.Split(";")).ToList().ForEach(i =>
{
string XA_EQ = i.FirstOrDefault();
string BK_EQ = i.Skip(1).FirstOrDefault();
my_func(XA_EQ, BK_EQ != null ? BK_EQ : "");
});
You don't get the actual value of XA or BK this way, but since you mention that this works for you I'm implementing the same logic.
string[] item_list = { "XA=12345678;BK=AZ31", "XA=87654321" };
foreach(string item in item_list)
{
if item.Contains('BK') {
string[] split = item.split(';');
my_func(split[0], split[1]);
} else {
my_func(item, null);
}
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I have a string like this
string input = "\r\n\r\nMaster = \r\nSlave\r\nRed =\r\n Blue";
What I want is that Master = Slave, Red= Blue so that I can create a dictionary.
The method that I am trying to use is:
1) String temp= Regex.Replace(str, “/r/n/r/n”, “”);
2) String temp= str.Replace(“/r/n/r/n”, “”);
Both the methods don’t seem to give me the result that I want. I even tried removing the white space but even that didn’t work out. Please help. Thank you.
It sounds like you have a string like this:
string Str = "Master = Slave\r\nRed = Blue";
And for output are you looking for something like this:
var dict = new Dictionary<string, string> { { "Master", "Slave" }, { "Red", "Blue" } };
If so, one way to do this is to first split the string on the newline characters, then split each of those on the equals character, and then add the resulting pair to a dictionary.
For example:
string input = "Master = Slave\r\nRed = Blue";
string[] keyValuePairs = input.Split( '\r', '\n');
Dictionary<string, string> dict = new Dictionary<string, string>();
foreach (var keyValuePair in keyValuePairs)
{
var parts = keyValuePair.Split('=');
if (parts.Length > 1)
{
dict.Add(parts[0].Trim(), parts[1].Trim());
}
}
// Result:
// dict
// Count = 2
// [0]: {[Master, Slave]}
// [1]: {[Red, Blue]}
The code above can be shortened using some System.Linq extension methods:
Dictionary<string, string> dict = input
.Split(new[] {'\r', '\n'}, StringSplitOptions.RemoveEmptyEntries)
.Select(kvp => kvp.Split('='))
.Where(parts => parts.Length > 1)
.ToDictionary(x => x[0].Trim(), x => x[1].Trim());
Another way to do this, since in the comments you've mentioned the newline characters may appear anywhere, is to examine the results after splitting the input on \r\n and splitting the result of that on the = character.
If the result has two parts, we have a key and a value, so add it to the dictionary. If there's only one part, and we haven't saved a key value yet, then save it as a key. Otherwise, add the saved key and this part as the value.
For example:
var input = "\r\n\r\nMaster = \r\nSlave\r\nRed =\r\n Blue";
var dict = new Dictionary<string, string>();
var currentKey = "";
foreach (var item in input.Split(new[] { '\r', '\n' },
StringSplitOptions.RemoveEmptyEntries))
{
var parts = item.Split(new[] { '=' },
StringSplitOptions.RemoveEmptyEntries);
if (currentKey.Length == 0)
{
if (parts.Length > 1 && !string.IsNullOrWhiteSpace(parts[1]))
{
dict.Add(parts[0].Trim(), parts[1].Trim());
}
else
{
currentKey = parts[0].Trim();
}
}
else
{
dict.Add(currentKey, parts.Length > 1
? parts[1].Trim()
: parts[0].Trim());
currentKey = "";
}
}
This question already has answers here:
How to check if a String contains any of some strings
(15 answers)
Closed 6 years ago.
I am just looking if there is a better way to do the following.
Say I have the following strings:
string fooWeb = "web";
string fooDesktop = "desktop";
string fooMac = "mac";
string fooIphone = "iphone";
string fooAndroid = "android";
list<string> Names = new List<string>();
Names.Add("web");
Names.Add("mac");
Names.Add("iphone");
Names.Add("android");
I am looping through this list and i want to exclude the item which contains for example "web" & "mac" & and "android" there could be others too.
Is there a better way to achieve this than what I am trying below:
foreach (var item in this._repo.FooRepo())
if (!(item.SystemName == "Web" || item.SystemName == "android" || item.SystemName == "mac"))
{
//add to new list
}
}
I am asking, as I have around 8 strings to check against.
You could through them into an array and use the .Contains() method.
var validItems = new [] { "Web", "android", "mac" };
foreach (var item in this._repo.FooRepo())
{
if (!validItems.Contains(item))
{
//add to new list
}
}
First part simplified:
list<string> Names = new List<string> () {
"web",
"mac",
"iphone",
"android"
};
or:
var Names = new [] {
"web",
"mac",
"iphone",
"android"
};
or:
string[] Names = new string[] {
"web",
"mac",
"iphone",
"android"
};
Second part simplified:
myList.Add(this._repo.FooRepo().Where(i => !Names.Contains(i.SystemName)));
You could create your own method to evaluate any number of strings, which can be used whenever - in a separate, static class:
public static class StringFunctions
{
public static bool IfContains(this string inString, params string[] comparisonStrings)
{
return comparisonStrings.Contains(inString);
}
}
This can be called like so
if(!item.SystemName.IfContains("web", "desktop", "mac", "iphone", "android"))
{
//add to new list
}
You can also pass an array into the method
string[] words = { "web", "desktop", "mac", "iphone", "android" };
if(!item.SystemName.IfContains(words))
{
//add to new list
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
The method looks as following:
private static List<string> SetPointObjectDefectRow(string[] row, string owner)
{
const int zone = 54;
const string band = "U";
if (Helpers.NormalizeLocalizedString(row[7]).Contains(#"a") ||
Helpers.NormalizeLocalizedString(row[12]).Contains(#"b"))
{
var geoPosition = UtmConverter.StringUtmFormatToLocation(zone, band, Convert.ToDouble(row[15]), Convert.ToDouble(row[14]));
var beginGeoPosition = geoPosition.LatString + ", " + geoPosition.LngString;
var result = new List<string>
{
owner,
row[4],
beginGeoPosition
};
return result;
}
}
It's obvious that not all paths return something and the issue is I can't return null.
How to rearrange the method?
Maybe you can initialize your List?
private static List<string> SetPointObjectDefectRow(string[] row, string owner)
{
const int zone = 54;
const string band = "U";
List<string> result = new List<string>()
{
owner,
string.Empty,
string.Empty
};
if (Helpers.NormalizeLocalizedString(row[7]).Contains(#"a") ||
Helpers.NormalizeLocalizedString(row[12]).Contains(#"b"))
{
var geoPosition = UtmConverter.StringUtmFormatToLocation(zone, band, Convert.ToDouble(row[15]), Convert.ToDouble(row[14]));
var beginGeoPosition = geoPosition.LatString + ", " + geoPosition.LngString;
result = new List<string>
{
owner,
row[4],
beginGeoPosition
};
}
return result;
}
I usually do this when I want to create an assembler method for example to tranform a List<X> to another List<Y>, so if my List<X> is null I try to return an empty List of Y. I prefer to do this instead of throwing exceptions and getting my Dashboard full of errors. But It depends on how your codes works.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have to parse this string
"Cust =Customer CustCR =Customer Credit Prod=Product SalesRep=Sales Rep TaxCat=Tax Category TaxId=Tax ID VolBill=Volume Billing"
as Code, Description like Code=Cust and Description=Customer
split on basis of space is not working for this because there is also a space in description too .
Instead of splitting on space you can split on the equals sign. Then the code will be the value after the last space of the previous item and the description will be everything up to the last space making sure to trim the spaces that might show up before the equals. And you can replace the Dictionary with whatever data type you want to load the values into. Also you have to handle the first and last values as special cases. Note this will only work if the codes do not contain spaces.
string str = "Cust =Customer CustCR =Customer Credit Prod=Product SalesRep=Sales Rep TaxCat=Tax Category TaxId=Tax ID VolBill=Volume Billing";
var separated = str.Split('=');
string code = separated[0].Trim();
var codeAndDescription = new Dictionary<string, string>();
for (int i = 1; i < separated.Length - 1; i++)
{
int lastSpace = separated[i].Trim().LastIndexOf(' ');
var description = separated[i].Substring(0, lastSpace).Trim();
codeAndDescription.Add(code, description);
code = separated[i].Substring(lastSpace + 1).Trim();
}
codeAndDescription.Add(code, separated[separated.Length - 1]);
foreach (var kvp in codeAndDescription)
Console.WriteLine(kvp);
Outputs
[Cust, Customer]
[CustCR, Customer Credit]
[Prod, Product]
[SalesRep, Sales Rep]
[TaxCat, Tax Category]
[TaxId, Tax ID]
[VolBill, Volume Billing]
A little modification for another case if description is empty, also used custom Item class to store output in a list
class Item {
public string Code { get; set; }
public string Description { get; set; }
}
class Program
{
static void Main(string[] args)
{
string str = "0= 1=Full Time 2=Part Time 3=Seasonal 4=Variable";
var separated = str.Split('=');
string code = separated[0].Trim();
var codeAndDescription = new List<Item>();
foreach (var sep in separated.Skip(1).Take(separated.Length - 2))
{
int lastSpace = sep.Trim().LastIndexOf(' ');
var description = lastSpace != -1 ? sep.Substring(0, lastSpace).Trim(): "" ;
codeAndDescription.Add(new Item { Code=code,Description=description });
code = sep.Substring(lastSpace + 1).Trim();
}
codeAndDescription.Add(new Item { Code = code, Description = separated.Last() });
foreach (var kvp in codeAndDescription)
{
Console.WriteLine("Code={0} Description={1}", kvp.Code, kvp.Description);
}
Console.ReadLine();
}
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I want to split string with "," but from 2nd comma(,)
haven't tried it, but you will need something like this:
string pattern = "|\*,";
string[] result = Regex.Split(before_split, pattern);
If you are looking for skip first ',' & then split rest of the string by ',' then you can try following.
string before_split = "pune,mumbai|01234,delhi|65432,Bhopal|09231,jabalpur|0987765";
var firstPart = before_split.Substring(0, before_split.IndexOf(",", System.StringComparison.Ordinal));
var stringToProcess = before_split.Substring(before_split.IndexOf(",", System.StringComparison.Ordinal) + 1);
var stringSegments = stringToProcess.Split(',');
Console.WriteLine("{0},{1}",firstPart ,stringSegments[0]);
for (var i = 1; i < stringSegments.Length; i++)
{
Console.WriteLine(stringSegments[i]);
}
Try this, the final result is on a List finalSplit
string before_split = "pune,mumbai|01234,333,222,delhi|65432,Bhopal|09231,jabalpur|0987765";
string[] split1 = before_split.Split(',');
List<string> finalSplit = new List<string>();
string aux = "";
foreach (string s in split1)
{
if (s.IndexOf('|') == -1)
aux = aux + s + ',';
else
{
if (aux == "")
aux = s;
else
aux = aux + s;
finalSplit.Add(aux);
aux = "";
}
}
Hope it helps
My solution is
string before_split = "pune,mumbai|01234,delhi|65432,Bhopal|09231,123,jabalpur|0987765";
string buffer = "";
var parts = before_split.Split(',');
var lines = parts.Select(p =>
{
if (p.Contains('|'))
{
var line = buffer == "" ? p : buffer + ',' + p;
buffer = "";
return line;
}
else
{
buffer = buffer == "" ? p : buffer + ',' + p;
return null;
}
}).Where(p => p != null).ToArray();
How about this...
Regex rex = new Regex("[a-zA-Z]+[a-zA-Z,]*[|]+[0-9]+");
var result = rex.Matches("pune,mumbai|01234,delhi|65432,Bhopal|09231,jabalpur|0987765").Cast<Match>()
.Select(m => m.Value)
.ToArray()
var result =before_split.Split(',')