List Collection Contains exact string - c#

I have a List Collection and say that i am adding 3 items to them.
list.Add(new ContentDomain() { Id = "1" , Content = "aaa,bbb,ccc,ddd"});
list.Add(new ContentDomain() { Id = "2" , Content = "aa,bb,cc,dd"});
list.Add(new ContentDomain() { Id = "3" , Content = "a,b,c,d"});
Now what i want is to fetch the rows that have just 'a' in the Content attribute.
Like i tried something like
list = list.Where(x => x.Content.ToLower().Contains("a")).ToList();
but that would give me all the three rows.
i want to search in a string for the exact string only.

list.Where(x => x.ToString().ToLower().Split(',').Where(a => a.Trim() == "a").Any()).ToList();
edit: Changed Count() > 0 to Any() for better performance

Convert it to an array of strings, and find the string in the array.
list = list.Where(x => x.Content.ToLower().Split(',').IndexOf("a")>= 0).ToList();

Try this:
IList<ContentDomain> returned = new List<ContentDomain>();
foreach(ContentDomain myList in list)
{
var ret = myList.Content.Split(',');
bool exists = (from val in ret
where val.Contains('a')
select true).FirstOrDefault();
if (exists)
returned.Add(myList);
}

Related

LINQ get find all with id in list

I am trying to figure out non query way to do return a list of all objects if their ID is in test list. Example below:
Hero - table
Columns: id = INT , name = STRING, age = INT, power = INT;
var testList = {1,2,3};
var secondArray = {};
foreach (var id in testList )
{
// check if ID in database
var item = db.Hero.ToList().Find(o => o.Id = id);
if( item != null)
{
secondArray.push(item);
}
}
Now i have seen this whole thing done in single line but cannot remember how it was done.
The result i am after is List of all objects containing that have ids 1,2,3.
You have to use Contains on testList:
var secondArray= db.Hero.Where (h=> testList.Contains(h.Id))
How about
var result = db.Hero.Where(x => testList.Contains(x.Id));
This would hit DB just once instead of 3 times.

Generating sublist of list given strings

I am very new to LINQ and am wondering if there is a way to extract a sublist from a list of strings given that the string values are provided beforehand.
For example, if I have:
var movies = new List<Movie>
{
new Movie { Name = "Noah" },
new Movie { Name = "Terminator" },
new Movie { Name = "Troy" },
new Movie { Name = "Gladiator" },
};
I would like to use LINQ to create a sublist if I provide the Name strings "Noah" and "Troy".
I have tried googling and results point me to SelectMany and GroupBy but all of the examples involve lists that contains primitive values, not primitives values contained in objects.
Is this what you are looking for?
var sublistItems = new List<string>() {"Noah", "Troy"} ;
var subList = movies.where(m=> sublistItems.Contains(m.Name));
var newlist = from m in movies
where (m.Name == "Troy" || m.Name == "Noah")
select m;
Using Linq lambda it would be:
var result = movies.where(x => x.Name == "Troy" || x.Name == "Noah");
This would return a IEnumerable<Movie> containing the ones searched for using Where.

TextBox display closest match string

How can I get the string from a list that best match with a base string using the Levenshtein Distance.
This is my code:
{
string basestring = "Coke 600ml";
List<string> liststr = new List<string>
{
"ccoca cola",
"cola",
"coca cola 1L",
"coca cola 600",
"Coke 600ml",
"coca cola 600ml",
};
Dictionary<string, int> resultset = new Dictionary<string, int>();
foreach(string test in liststr)
{
resultset.Add(test, Ldis.Compute(basestring, test));
}
int minimun = resultset.Min(c => c.Value);
var closest = resultset.Where(c => c.Value == minimun);
Textbox1.Text = closest.ToString();
}
In this example if I run the code I get 0 changes in string number 5 from the list, so how can I display in the TextBox the string itself?
for exemple : "Coke 600ml" Right now my TextBox just returns:
System.Linq.Enumerable+WhereEnumerableIterator`1
[System.Collections.Generic.KeyValuePair`2[System.String,System.Int32]]
Thanks.
Try this
var closest = resultset.First(c => c.Value == minimun);
Your existing code is trying to display a list of items in the textbox. I looks like it should just grab a single item where Value == min
resultset.Where() returns a list, you should use
var closest = resultset.First(c => c.Value == minimun);
to select a single result.
Then the closest is a KeyValuePair<string, int>, so you should use
Textbox1.Text = closest.Key;
to get the string. (You added the string as Key and changes count as Value to resultset earilier)
There is a good solution in code project
http://www.codeproject.com/Articles/36869/Fuzzy-Search
It can be very much simplified like so:
var res = liststr.Select(x => new {Str = x, Dist = Ldis.Compute(basestring, x)})
.OrderBy(x => x.Dist)
.Select(x => x.Str)
.ToArray();
This will order the list of strings from most similar to least similar.
To only get the most similar one, simply replace ToArray() with First().
Short explanation:
For every string in the list, it creates an anonymous type which contains the original string and it's distance, computed using the Ldis class. Then, it orders the collection by the distance and maps back to the original string, so as to lose the "extra" information calculated for the ordering.

Compare value to array of strings using StartsWith

I have an array:
string[] exceptions = new string[] { "one", two", "one_1", "three" };
.. I want to be able to say:
var result = from c in myCollection
where not c.Property[3].Value.StartWith(exceptions)
select c;
So I want myCollection to be filtered to only show those records whose Property[3].Value does not StartWith a value in the exceptions array. I know StartsWith doesn't take a collection so I'm unsure if this is possible via LINQ or not.
Is this possible in LINQ?! Or am I trying to shoehorn my problem into a LINQ solution?
EDIT: I should say, Contains is not an option since I only want to exclude elements whose property startswith the exception string.
var result = myCollection.Where(c =>
exceptions.All(e =>
!c.Property[3].Value.StartsWith(e));
Try this:
string[] exceptions = new string[] { "one", "two", "one_1", "three" };
var result = from c in myCollection
where !exceptions.Any(exception =>
c.Property[3].Value.StartsWith(exception))
select c;
You could use IndexOfAny (and check result is index position zero) as that takes a collection.
You can select the collection of item you don't want then do a IEnumerable.Except().
I should look like this :
var result = from c in myCollection
where not c.Property[3].Value.StartWith(exceptions)
select c;
var finalResult = myCollection.Except(myCollection.Select(i => i.StartWith(exception)));
var result = myCollection
.where(
rs=>exceptions
.where(
rs1=>!rs.property[3].value.startsWith(rs1)
)
)

Get Count in List of instances contained in a string

I have a string containing up to 9 unique numbers from 1 to 9 (myString) e.g. "12345"
I have a list of strings {"1"}, {"4"} (myList) .. and so on.
I would like to know how many instances in the string (myString) are contained within the list (myList), in the above example this would return 2.
so something like
count = myList.Count(myList.Contains(myString));
I could change myString to a list if required.
Thanks very much
Joe
I would try the following:
count = mylist.Count(s => myString.Contains(s));
It is not perfectly clear what you need, but these are some options that could help:
myList.Where(s => s == myString).Count()
or
myList.Where(s => s.Contains(myString)).Count()
the first would return the number of strings in the list that are the same as yours, the second would return the number of strings that contain yours. If neither works, please make your question more clear.
If myList is just List<string>, then this should work:
int count = myList.Count(x => myString.Contains(x));
If myList is List<List<string>>:
int count = myList.SelectMany(x => x).Count(s => myString.Contains(s));
Try
count = myList.Count(s => s==myString);
This is one approach, but it's limited to 1 character matches. For your described scenario of numbers from 1-9 this works fine. Notice the s[0] usage which refers to the list items as a character. For example, if you had "12" in your list, it wouldn't work correctly.
string input = "123456123";
var list = new List<string> { "1", "4" };
var query = list.Select(s => new
{
Value = s,
Count = input.Count(c => c == s[0])
});
foreach (var item in query)
{
Console.WriteLine("{0} occurred {1} time(s)", item.Value, item.Count);
}
For multiple character matches, which would correctly count the occurrences of "12", the Regex class comes in handy:
var query = list.Select(s => new
{
Value = s,
Count = Regex.Matches(input, s).Count
});
try
var count = myList.Count(x => myString.ToCharArray().Contains(x[0]));
this will only work if the item in myList is a single digit
Edit: as you probably noticed this will convert myString to a char array multiple times so it would be better to have
var myStringArray = myString.ToCharArray();
var count = myList.Count(x => myStringArray.Contains(x[0]));

Categories