From the given string
(i.e)
string str = "dry sky one two try";
var nonVowels = str.Split(' ').Where(x => !x.Contains("aeiou")); (not working).
How can i extract non-vowel words?
Come on now y'all. IndexOfAny is where it's at. :)
// if this is public, it's vulnerable to people setting individual elements.
private static readonly char[] Vowels = "aeiou".ToCharArray();
// C# 3
var nonVowelWorks = str.Split(' ').Where(word => word.IndexOfAny(Vowels) < 0);
// C# 2
List<string> words = new List<string>(str.Split(' '));
words.RemoveAll(delegate(string word) { return word.IndexOfAny(Vowels) >= 0; });
This should work:
var nonVowels = str.Split(' ').Where(x => x.Intersect("aeiou").Count() == 0);
String.Contains requires you to pass a single char. Using Enumerable.Contains would only work for a single char, as well - so you'd need multiple calls. Intersect should handle this case.
Something like:
var nonVowelWords = str.Split(' ').Where(x => Regex.Match(x, #"[aeiou]") == null);
string str = "dry sky one two try";
var nonVowels = str.ToCharArray()
.Where(x => !new [] {'a', 'e', 'i', 'o', 'u'}.Contains(x));
Related
I'm trying to get a list of Vendors' names where the name starts with a character between A and E. Is there a way to do that perhaps using LINQ?
My current solution is just a very long if statement
var vendors = _context.Vendors.ToList();
var sortedVendors = new List<Vendor>();
foreach (Vendor vendor in vendors)
{
if (vendor.Name.StartsWith('A') ||
vendor.Name.StartsWith('B') ||
vendor.Name.StartsWith('C') ||
vendor.Name.StartsWith('D') ||
vendor.Name.StartsWith('E'))
{
sortedVendors.Add(vendor);
}
}
This works, but is hideous and I would love to know if there was a more elegant solution
Another option is a regular expression. For testing if a string begins with A through E, the regex is ^[A-E].
var range = new Regex("^[A-E]");
List<Vendor> sortedVendors = vendors.Where(v => range.IsMatch(v.Name)).ToList();
For a non-case sensitive comparison, set the IgnoreCase option when creating the regex.
var range = new Regex("^[A-E]", regexOptions.IgnoreCase);
List<Vendor> sortedVendors = vendors.Where(v => range.IsMatch(v.Name)).ToList();
To modularize, create a method that accepts the vendor list, the start of the range, and the end of the range. This implementation is not case sensitive:
public List<Vendor> GetRange(List<Vendor> vendorList, char rangeFrom, char rangeThru)
{
var range = new Regex($"^[{rangeFrom}-{rangeThru}]", regexOptions.IgnoreCase);
return vendorList.Where(v => range.IsMatch(v.Name)).ToList();
}
Then call as sortedList = whatever.GetRange(vendors, 'A', 'E');
This is how I would do it
var charsToCheck = new char[] { 'A', 'B', 'C', 'D', 'E' };
var sortedVendors = vendors.Where(vendor => charsToCheck.Contains(vendor[0])).ToList();
To make it clear and readable I think I would do this:
string startsWiths = "ABCDEF";
IEnumerable<Vendor> query =
from v in vendors
where startsWiths.Any(c => v.Name.StartsWith(c))
select v;
List<Vendor> sortedVendors = query.ToList();
Using pattern matching, it could be more intuitive.
_context.Vendors.Where(v => v.Name is { Length: > 0 } && v.Name[0] is 'A' or 'B' or 'C' or 'D' or 'E').ToList()
I pass a string containing separate characters on each line to a Unicode list with this code.
string MultiLineCharArray = string.Join(Environment.NewLine, CharArray);
var UnicodeList = MultiLineCharArray.Select(str => Convert.ToUInt16(str)).ToList();
when reversing it the program dies, it does not even try, very badly:
for (int i = 0; i < UnicodeList.Count; i++)
{
MultiLineCharArray = string.Join(Environment.NewLine, Convert.ToChar(UnicodeList[i]));
}
I need the MultiLineCharArray to then convert it into an Array of its valid Unicode characters (unicode = A) going through each line to convert it to a single string.
The Unicode list is very long (9,000) elements, maybe that's why the program crashed, is there a more optimal way to do it?
Use LINQ and String functions
// to populate charArray with dummy chars A through J
var charArray = Enumerable.Range(65, 10).Select(i => (char)i);
// your existing code
var multiLineCharArray = string.Join(Environment.NewLine, charArray);
var unicodeList = multiLineCharArray.Select(str => Convert.ToUInt16(str)).ToList();
// to reverse
var multiLineCharArray1 = new string(unicodeList.Select(u => (char)u).ToArray());
var charArray1 = multiLineCharArray1.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
I want to find a string of fixed length with specific substring. But I need to do it like we can do in SQL queries.
Example:
I have strings like -
AB012345
AB12345
AB123456
AB1234567
AB98765
AB987654
I want to select strings that have AB at first and 6 characters afterwards. Which can be done in SQL by SELECT * FROM [table_name] WHERE [column_name] LIKE 'AB______' (6 underscores after AB).
So the result will be:
AB012345
AB123456
AB987654
I need to know if there is any way to select strings in such way with C#, by using AB______.
You can use Regular Expressions to filter the result:
List<string> sList = new List<string>(){"AB012345",
"AB12345",
"AB123456",
"AB1234567",
"AB98765",
"AB987654"};
var qry = sList.Where(s=>Regex.Match(s, #"^AB\d{6}$").Success);
Considering you have an string array:
string[] str = new string[3]{"AB012345", "A12345", "AB98765"};
var result = str.Where(x => x.StartsWith("AB") && x.Length == 8).ToList();
The logic is if it starts with AB, and its length is 8. It is your best match.
this should do it
List<string> sList = new List<string>(){
"AB012345",
"AB12345",
"AB123456",
"AB1234567",
"AB98765",
"AB987654"};
List<string> sREsult = sList.Where(x => x.Length == 8 && x.StartsWith("AB")).ToList();
first x.Length == 8 determines the length and x.StartsWith("AB") determines the required characters at the start of the string
This can be achieved by using string.Startwith and string.Length function like this:
public bool CheckStringValid (String input)
{
if (input.StartWith ("AB") && input.Length == 8)
{
return true;
}
else
{
return false;
}
}
This will return true if string matches your criteria.
Hope this helps.
var strlist = new List<string>()
{
"AB012345",
"AB12345",
"AB123456",
"AB1234567",
"AB98765",
"AB987654"
};
var result = strlist.Where(
s => (s.StartsWith("AB") &&(s.Length == 8))
);
foreach(var v in result)
{
Console.WriteLine(v.ToString());
}
In C# what would be the best way of splitting this sort of string?
%%x%%a,b,c,d
So that I end up with the value between the %% AND another variable containing everything right of the second %%
i.e. var x = "x"; var y = "a,b,c,d"
Where a,b,c.. could be an infinite comma seperated list. I need to extract the list and the value between the two double-percentage signs.
(To combat the infinite part, I thought perhaps seperating the string out to: %%x%% and a,b,c,d. At this point I can just use something like this to get X.
var tag = "%%";
var startTag = tag;
int startIndex = s.IndexOf(startTag) + startTag.Length;
int endIndex = s.IndexOf(tag, startIndex);
return s.Substring(startIndex, endIndex - startIndex);
Would the best approach be to use regex or use lots of indexOf and substring to do the extracting based on te static %% characters?
Given that what you want is "x,a,b,c,d" the Split() function is actually pretty powerful and regex would be overkill for this.
Here's an example:
string test = "%%x%%a,b,c,d";
string[] result = test.Split(new char[] { '%', ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string s in result) {
Console.WriteLine(s);
}
Basicly we ask it to split by both '%' and ',' and ignore empty results (eg. the result between "%%"). Here's the result:
x
a
b
c
d
To Extract X:
If %% is always at the start then;
string s = "%%x%%a,b,c,d,h";
s = s.Substring(2,s.LastIndexOf("%%")-2);
//Console.WriteLine(s);
Else;
string s = "v,u,m,n,%%x%%a,b,c,d,h";
s = s.Substring(s.IndexOf("%%")+2,s.LastIndexOf("%%")-s.IndexOf("%%")-2);
//Console.WriteLine(s);
If you need to get them all at once then use this;
string s = "m,n,%%x%%a,b,c,d";
var myList = s.ToArray()
.Where(c=> (c != '%' && c!=','))
.Select(c=>c).ToList();
This'll let you do it all in one go:
string pattern = "^%%(.+?)%%(?:(.+?)(?:,|$))*$";
string input = "%%x%%a,b,c,d";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
// "x"
string first = match.Groups[1].Value;
// { "a", "b", "c", "d" }
string[] repeated = match.Groups[2].Captures.Cast<Capture>()
.Select(c => c.Value).ToArray();
}
You can use the char.IsLetter to get all the list of letter
string test = "%%x%%a,b,c,d";
var l = test.Where(c => char.IsLetter(c)).ToArray();
var output = string.Join(", ", l.OrderBy(c => c));
Since you want the value between the %% and everything after in separate variables and you don't need to parse the CSV, I think a RegEx solution would be your best choice.
var inputString = #"%%x%%a,b,c,d";
var regExPattern = #"^%%(?<x>.+)%%(?<csv>.+)$";
var match = Regex.Match(inputString, regExPattern);
foreach (var item in match.Groups)
{
Console.WriteLine(item);
}
The pattern has 2 named groups called x and csv, so rather than just looping, you can easily reference them by name and assign them to values:
var x = match.Groups["x"];
var y = match.Groups["csv"];
I have string, I need split it two times and select part which goes after special character.
Lets say:
string myString = "Word 2010|82e146e7-bc85-4bd4-a691-23d55c686f4b;#Videos|55140947-00d0-4d75-9b5c-00d8d5ab8436";
string[] guids = Regex.Split(myString,";#");
So here I am getting array of two elements with Value + GUID. But I need only Guids, like:
[0]82e146e7-bc85-4bd4-a691-23d55c686f4b
[1]55140947-00d0-4d75-9b5c-00d8d5ab8436
Any way of doing it in one/two lines?
You can do this but just because you can do it in one line doesn't mean you should (readability comes into play if you get too fancy here). There's obviously no validation here at all.
string myString = "Word 2010|82e146e7-bc85-4bd4-a691-23d55c686f4b;#Videos|55140947-00d0-4d75-9b5c-00d8d5ab8436";
string[] guids = Regex.Split(myString, ";#")
.SelectMany(s => Regex.Split(s, #"\|").Skip(1))
.ToArray();
Assert.AreEqual(2, guids.Length);
Assert.AreEqual("82e146e7-bc85-4bd4-a691-23d55c686f4b", guids[0]);
Assert.AreEqual("55140947-00d0-4d75-9b5c-00d8d5ab8436", guids[1]);
You could easily do this without a regex if the last part of each is always a guid:
string[] guids = String.Split(";").Select(c => c.Substring(c.Length - 36)).ToArray();
string[] guids = myString.Split(';').Select(x => x.Split('|')[1]).ToArray();
string myString = "Word 2010|82e146e7-bc85-4bd4-a691-23d55c686f4b;#Videos|55140947-00d0-4d75-9b5c-00d8d5ab8436";
//split the string by ";#"
string[] results = myString.Split(new string[] { ";#" }, StringSplitOptions.RemoveEmptyEntries);
//remove the "value|" part
results[0] = results[0].Substring(results[0].IndexOf('|') + 1);
results[1] = results[1].Substring(results[1].IndexOf('|') + 1);
//Same as above, but in a for loop. usefull if there are more then 2 guids to find
//for(int i = 0; i < results.Length; i++)
// results[i] = results[i].Substring(results[i].IndexOf('|') + 1);
foreach(string result in results)
Console.WriteLine(result);
var guids = Regex
.Matches(myString, #"HEX{8}-HEX{4}-HEX{4}-HEX{4}-HEX{12}".Replace("HEX", "[A-Fa-f0-9]"))
.Cast<Match>()
.Select(m => m.Value)
.ToArray();