Compare two comma separated strings and get count of intersecting values - linq

What is the best code for comparing 2 comma separated strings and retrieving values that intersect? For instance lets say I have string "a,b,c" and the target string "x,b,y", I need result saying there is 1 occurrence.
As suggested here One way of doing this is
public static bool UserCanAccessThisPage(string userAccessGroups,
string pageItemAccessGroups)
{
return userAccessGroups.Split(',')
.Select(s => s.Trim())
.Contains(pageItemAccessGroups);
}
But this will only check the match but I do also need occurrences. Any suggestions please

Use Enumerable.Intersect to get intersection of two sequences:
var occurrences =
userAccessGroups.Split(',').Select(s => s.Trim())
.Intersect(pageItemAccessGroups.Split(',').Select(s => s.Trim()));
Checking if occurrences exist:
bool exist = occurrences.Any();
Getting occurrences count:
int count = occurrences.Count();
To make code more readable you can store groups in local variables:
// this can be ordinal named method
Func<string, IEnumerable<string>> parse =
csv => csv.Split(',').Select(s => s.Trim());
var userGroups = parse(userAccessGroups);
var pateItemGroups = parse(pageItemAccessGroups);
var occurrences = userGroups.Intersect(pageItemGroups);

Related

Dart custom sorting of a list

I want to build a suggestion builder where I want to display search suggestions on changing the text in TextField. I want to search on the basis of contains method but I want to sort that particular list on the basis of startsWith, If I only use startsWith it neglects all other contains, How can I apply both simultaneously?
I have a List,
List<String> list = ["apple", "orange", "aaaaorange", "bbbborange","cccccorange"]
Now If I put only ora in search it's returning me in the following order,
aaaaorange
bbbborange
cccccorange
orange
What I want.
orange
aaaaorange
bbbborange
cccccorange
Code:
return list
.where((item) {
return item.toLowerCase().contains(query.toLowerCase());
}).toList(growable: false)
..sort((a, b) {
return a.toLowerCase().compareTo(b.toLowerCase());
});
It may be easiest to think of the two queries separately, and then combine the results:
var list = <String>[
'apple',
'orange',
'aaaaorange',
'bbbborange',
'cccccorange',
];
var pattern = 'ora';
var starts = list.where((s) => s.startsWith(pattern)).toList();
var contains = list
.where((s) => s.contains(pattern) && !s.startsWith(pattern))
.toList()
..sort((a, b) => a.toLowerCase().compareTo(b.toLowerCase()));
var combined = [...starts, ...contains];
print(combined);

Split and validate text that contains brackets, commas and integers

How can i split text which contains only brackets, commas and 3 integers. For example:
{5,40,30}
I also want to validate that it looks like above.
Try this using regex.
var testString = "12,23,{23,23},23,{51,22,345}{{]}1123,{12,12,232,123}{{33,33,33}}";
var regex = new Regex(#"{\d+,\d+,\d+}");
var matches = regex.Matches(testString);
The output of the above test string after match is
{51,22,345} and {33,33,33}
Here's a non regex solution using string methods and LINQ which i prefer:
string text = "{5,40,30}";
bool valid = text.StartsWith("{") && text.EndsWith("}");
int[] integers = {};
if (valid)
{
integers = text.Trim('{', '}').Split(',')
.Select(s => s.TryGetInt32())
.Where(nullInt => nullInt.HasValue)
.Select(nullInt => nullInt.Value)
.ToArray();
valid = integers.Length == 3;
}
using this handy extension method that i use in LINQ queries to get a Nullabel<int> from a string, so similar to int.TryParse but with an int?.
public static int? TryGetInt32(this string item)
{
int i;
bool success = int.TryParse(item, out i);
return success ? (int?)i : (int?)null;
}

IQueryable .Except() is not resulting what I expect!

I have the following object:
Line{ String Content; Type type;}
And I have, IQeryable<Line> lines, which I perform operations against. I selected certain lines where line.Content.Contains('x') = list1, and now am trying to get to the rest of the lines i.e. lines - list1 and for this am using
list2 = lines.Except(list1);
but that results in list2 = lines.
Code:
private
IQueryable<Line>
ExtractLines(
IQueryable<Line> allLines,
String keyword,
ref IQueryable<Line> hits)
{
hits = allLines.Where(lx => lx.Content.Contains(keyword));
return allLines.Except(hits);
}
any ideas?
Alright. All I needed to do is to implement IEqualityComparer<T> in Line class.
lines is IQeryable<Line>. If you do not save its result, it will run every time you select from it. If Line does not override Equals and ==, that will create different objects each time, so Except cannot remove the previous object from new objects.
Now, a lot is missing, but try:
var linesList = lines.ToList(); // get results ones
var hasX = lines.Where(line => line.Content.Contains('x'));
var noX = lines.Except(hasX);

LINQ: Entity string field contains any of an array of strings

I want to get a collection of Product entities where the product.Description property contains any of the words in a string array.
It would look something like this (result would be any product which had the word "mustard OR "pickles" OR "relish" in the Description text):
Dim products As List(Of ProductEntity) = New ProductRepository().AllProducts
Dim search As String() = {"mustard", "pickles", "relish"}
Dim result = From p In products _
Where p.Description.Contains(search) _
Select p
Return result.ToList
I already looked at this similar question but couldn't get it to work.
Since you want to see if search contains a word which is contained in the description of p you basically need to test for each value in search if it is contained in the description of p
result = from p in products
where search.Any(val => p.Description.Contains(val))
select p;
This is c# syntax for the lambda method since my vb is not that great
Dim result = From p in products _
Where search.Any(Function(s) p.Description.Contains(s))
Select p
You can use a simple LINQ query, if all you need is to check for substrings:
var q = words.Any(w => myText.Contains(w));
// returns true if myText == "This password1 is weak";
If you want to check for whole words, you can use a regular expression:
Matching against a regular expression that is the disjunction of all the words:
// you may need to call ToArray if you're not on .NET 4
var escapedWords = words.Select(w => #"\b" + Regex.Escape(w) + #"\b");
// the following line builds a regex similar to: (word1)|(word2)|(word3)
var pattern = new Regex("(" + string.Join(")|(", escapedWords) + ")");
var q = pattern.IsMatch(myText);
Splitting the string into words with a regular expression, and testing for membership on the words collection (this will get faster if you use make words into a HashSet instead of a List):
var pattern = new Regex(#"\W");
var q = pattern.Split(myText).Any(w => words.Contains(w));
In order to filter a collection of sentences according to this criterion all you have to do its put it into a function and call Where:
// Given:
// bool HasThoseWords(string sentence) { blah }
var q = sentences.Where(HasThoseWords);
Or put it in a lambda:
var q = sentences.Where(s => Regex.Split(myText, #"\W").Any(w => words.Contains(w)));
Ans From => How to check if any word in my List<string> contains in text by #R. Martinho Fernandes

Filtering a List with another List Inclusive

i have a list of filter names: FILTERBYNAMES
my query result items each contain a name list: NAMES
I want to filter the result an take all items whose name list contains at least one name in the FILTERNAMELIST:
results= result.where(r=>r.NAMES.CONTAINS(...?)...?
I think you need something like:
var results = list.Where(i => i.Names
.Any(name => filterNameList.Contains(name)));
You can solve this by looking at the intersection of the two name sets.
var filteredResult = result.Where(i => i.Names.Intersect(filter).Any());
To limit the enumerations of the filter, you could use a hashset...
HashSet<string> hashedFilter = new HashSet<string>(filterByNames);
var results = result
.Where(x => x.Names
.Any(name => hashedFilter.Contains(name))
);

Resources