Regex to split
CustomerID, PaymentAmount, Date, EmailDateFourDays, RefNo
CustomerID
PaymentAmount
Date
EmailDateFourDays
RefNo
Regex.Split(fieldValue, "[\\s;,]" , RegexOptions.IgnoreCase)
I am getting empty value
Based on this answer, you can simply filter it out by:
var result = Regex.Split(fieldValue, "[\s;,]" , RegexOptions.IgnoreCase)
.Where(s => s != String.Empty);
You can use Where() to remove all empty elements,
var result = Regex.Split(fieldValue, "[\\s;,]" , RegexOptions.IgnoreCase)
.Where(x => !string.IsNullOrEmpty(x)) //Filter non empty strings
.ToList() //Convert to list
In a Fiddle, I tested this to work on (what I assume to be) your input:
using System;
public class Program
{
public static void Main()
{
var input =
#"CustomerID
PaymentAmount
Date
EmailDateFourDays
RefNo";
Console.WriteLine(string.Join("|",input.Split(new char[]{' ', '\n'}, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)));
}
}
It's not Regex but produces the output:
CustomerID|PaymentAmount|Date|EmailDateFourDays|RefNo
which indicates, all fields have been found and empty ones removed.
Related
Please help on converting a list of objects got from DB into substrings separated by a comma
Take for example I have a sample code below:
List<string> CategoryNames = new List<string>();
CategoryNames.Add("myName1");
CategoryNames.Add("myName2");
CategoryNames.Add("myName3");
I want to convert CategoryNames into a format like this
"myName1","myName2","myName3"
From the above CatgoryNames happen to be retrieved from db.
var categoryNames = _context.BillingCategory.ToList();
How do I convert the categoryNames into substrings as shown above?
Any help will be appreciated.
You can use String.Join() method by combining with LINQ for preserving the quotes before joining:
var result = String.Join(",", CategoryNames.Select(item => $"\"{item}\""));
And here is the clearer version of the code if you don't linke singleliner:
var QuotedCategroyNames = CategoryNames
.Select(item => $"\"{item}\"");
var result = String.Join(",", QuotedCategroyNames);
Use LINQ Select to enclose all names in quotes, then string.Join to merge back into a comma separated string.
string.Join(',', CategoryNames.Select(n => '"' + n + '"'));
You can use string.Join() and concat with the double quotes character :
var serialized = $#"""{ string.Join(#""",""", CategoryNames) }"""; // "myName1","myName2","myName3"
Try it yourself
I have a string str = "abc,def,ghi". The length of string will vary. There could be one or more values separated by comma.
I have an object that has a property Code that is string and can contain values such as - "abc, stu, xyz"
I'm trying to filter objects from a collection that will return only those that contain a string in str
So, if object.Code = "abc, stu, xyz" and string str = "abc,def,ghi" then return the object.
objects.Where( x => x.Code.Split(',').Any(s => (???)) );
where ??? is where my string str values will come in.
Thanks,
var result = objects.Where(x => x.Code.Split(',').Any(s => (str.Split(',').Any(f => f.Equals(s)))));
Conversion of the str to a HashSet will improve the testing speed and simplify the query, but perhaps is overkill if your objects only have a few entries. I assume the Code property does not have spaces after each comma.
var strHash = str.Split(',').ToHashSet();
var ans = objects.Where(o => o.Code.Split(',', StringSplitOptions.RemoveEmptyEntries).Any(c1 => strHash.Contains(c1)));
Problem
Background Story: I am rewriting all SQL queries of legacy system into LINQ.
The database is not as clean as I expect. As many of these SQL record contains spaces or different cases which treated as the same.
SELECT *
FROM fruit
WHERE name = #fruitname;
Provided #fruitname is apple, this query will match any record ends with apple, _apple, APPLE_ (where _ is a whitespace character).
However, This is the expected behavior in my use cases.
On the otherhand, LINQ string comparison is more precise. Which annoys me because such issues keep surfacing to me.
Setup
FruitTableAdapter fruitsAdapter = new FruitTableAdapter();
MyGardenDataSet.FruitDataTable fruitsTable = fruitsAdapter.GetData();
Approaches
// Issue 1: Does not match, '_apple' or 'APPLE_'
var fruits1 = fruitsTable.Where(row=>row.name == fruitname);
// Issue 2: String Comparison with case insensitive (does not match 'APPLE')
var fruits2 = fruitsTable.Where(
row=>row.nameEquals(fruitname, StringComparison.OrdinalIgnoreCase));
// Issue 3: Trailing space with case insensitive
var fruits2 = fruitsTable.Where(
row=>row.name.Trim().Equals(fruitname.Trim(),
StringComparison.OrdinalIgnoreCase));
I'm not sure but there could be many issues which SQL query are different from String Comparison.
Is there any SQL aware StringComparison? How can I achieve the same string comparison as SQL in LINQ?
Here's a nice String Extension method that builds on the solutions from a similiar question about casing StackOverflow
Keep in mind, we want to allow for NULL strings in our trim scenarios, so this extension will do a Case Insensitive compare on Trimmed strings after checking for null values
public static class StringExtension
{
// Trim strings and compare values without casing
public static bool SqlCompare(this string source, string value)
{
// Handle nulls before trimming
if (!string.IsNullOrEmpty(source))
source = source.Trim();
if (!string.IsNullOrEmpty(value))
value = value.Trim();
// Compare strings (case insensitive)
return string.Equals(source, value, StringComparison.CurrentCultureIgnoreCase);
}
}
Here's how to use the Extension in your LINQ statement:
(SysUserDisplayFavorites table is composed of char() fields with space filled results. These will get trimmed and compared (case insensitive) to the user provided values in displayFavorite object)
var defaultFavorite = _context.SysUserDisplayFavorites
.Where(x => x.UserId.SqlCompare(displayFavorite.UserId))
.Where(x => x.ModuleCode.SqlCompare(displayFavorite.ModuleCode))
.Where(x => x.ActivityCode.SqlCompare(displayFavorite.ActivityCode))
.Where(x => x.ActivityItemCode.SqlCompare(displayFavorite.ActivityItemCode))
.Where(x => x.IsDefault);
This is a very late answer.
You can use Regex to solve your problem
Here's what I have tried, hope it helps
I created a sample class
public class SampleTable
{
public string Name { get; set; }
public SampleTable(string name)
{
Name = name;
}
}
Populated sample data
List<SampleTable> sampleTblList = new List<SampleTable>();
sampleTblList.Add(new SampleTable(" Apple"));
sampleTblList.Add(new SampleTable(" APPLE"));
sampleTblList.Add(new SampleTable("Apple"));
sampleTblList.Add(new SampleTable("apple"));
sampleTblList.Add(new SampleTable("apple "));
sampleTblList.Add(new SampleTable("apmangple"));
Solution:-
string fruitName = "apple";
List<SampleTable> sortedSampleTblList = sampleTblList.Where(x =>
Regex.IsMatch(fruitName, x.Name, RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase)).ToList();
Output:-
string ans = String.Join(",", sortedSampleTblList.Select(x => x.Name.Replace(" ","_")).ToArray());
Console.Write(ans);
_Apple,_APPLE,Apple,apple,apple_
fruitsTable.Where(row => row.name.Trim().Equals(fruitname, StringComparison.OrdinalIgnoreCase)); should do what you need, but I'm confused because you've listed almost the same under Issue 3. Were you not realising it was working because you are reusing fruits2?
This little NUnit test is passing
[Test]
public void FruitTest()
{
var fruitsTable = new List<string> { " Apple", " APPLE", "Apple", "apple", "apple ", " apple", "APPLE " };
var fruitname = "apple ".Trim();
var fruits = fruitsTable.Where(row => row.Trim().Equals(fruitname, StringComparison.OrdinalIgnoreCase));
Assert.AreEqual(fruitsTable.Count(), fruits.Count());
}
My values come from ComboBox:
2|722|742|762|77
I delete unnecessary characters as follows:
foreach (var item in checkListBox)
{
string[] list = item.Split(
new string[] { "2|" },
StringSplitOptions.RemoveEmptyEntries);
}
My list values result:
"72"
"74"
"76"
"77"
My question is:
how can I get all of the above values in 1 row (next to each other) separated by comma like this:
72,74,76,77
?
It sounds like you just want string.Join:
string commaSeparated = string.Join(",", list);
(Note that this is not part of LINQ - it's not the same kind of "join" as for joining multiple sequences. It's joining several strings together with a separator.)
While you can do this in a single statement as per the currently accepted answer, I'd personally consider leaving your existing statement and having this as a separate step. It makes the code easier to both read and debug.
String.Join(",",list);
Though: a) This is not Linq. b) As is mentioned in another answer here - It would be simpler in this case to use Replace.
Using Linq:
list.Select(s => s + ",").Aggregate((s, q) => s + q).TrimEnd(',');
How about
var result = string.Join(",", item.Split(new string[] { "2|" }, StringSplitOptions.RemoveEmptyEntries));
Just use Replace directly:
string input = "2|722|742|762|77";
var result = input.Replace("2|",",").Trim(',');
As noted in the other answers, string.Join is what should be used here. If you'd however insist on LINQ:
var result = list
.Skip(1)
.Aggregate(
list.FirstOrDefault() ?? string.Empty,
(total, current) => total + "," + current);
Have a string like A=B&C=D&E=F, how to remove C=D part and get the string like A=B&E=F?
Either just replace it away:
input.Replace("&C=D", "");
or use one of the solutions form your previous question, remove it from the data structure and join it back together.
Using my code:
var input = "A=B&C=D&E=F";
var output = input
.Split(new string[] {"&"}, StringSplitOptions.RemoveEmptyEntries)
.Select(s => s.Split('=', 2))
.ToDictionary(d => d[0], d => d[1]);
output.Remove("C");
output.Select(kvp => kvp.Key + "=" + kvp.Value)
.Aggregate("", (s, t) => s + t + "&").TrimRight("&");
using System.Web; // for HttpUtility
NameValueCollection values = HttpUtility.ParseQueryString("A=B&C=D&E=F");
values.Remove("C");
values.ToString(); // "A=B&E=F"
I think you need to give a clearer example to make sure it's something for the situation, but something like this should do that:
var testString = "A=B&C=D&E=F"
var stringArray = testString.Split('&');
stringArray.Remove("C=D");
var output = String.Join("&", stringArray);
Something like that should work, and should be pretty dynamic
You can either split() and manually join (depending how the data looks like) or simly use string.Replace(,string.empty)
Split it on the & separator, exclude the C=D part by some mechanism, then join the remaining two? The String class provides the methods you'd need for that, including splitting, joining and substring matching.
string xyz = "A=B&C=D&E=F";
string output = xyz.Replace("&C=D","");
Output: A=B&E=F