Related
Suppose I have a list of strings [city01, city01002, state02, state03, city04, statebg, countryqw, countrypo]
How do I group them in a dictionary of <string, List<Strings>> like
city - [city01, city04, city01002]
state- [state02, state03, statebg]
country - [countrywq, countrypo]
If not code, can anyone please help with how to approach or proceed?
As shown in other answers you can use the GroupBy method from LINQ to create this grouping based on any condition you want. Before you can group your strings you need to know the conditions for how a string is grouped. It could be that it starts with one of a set of predefined prefixes, grouped by whats before the first digit or any random condition you can describe with code. In my code example the groupBy method calls another method for every string in your list and in that method you can place the code you need to group the strings as you want by returning the key to group the given string under. You can test this example online with dotnetfiddle: https://dotnetfiddle.net/UHNXvZ
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
List<string> ungroupedList = new List<string>() {"city01", "city01002", "state02", "state03", "city04", "statebg", "countryqw", "countrypo", "theFirstTown"};
var groupedStrings = ungroupedList.GroupBy(x => groupingCondition(x));
foreach (var a in groupedStrings) {
Console.WriteLine("key: " + a.Key);
foreach (var b in a) {
Console.WriteLine("value: " + b);
}
}
}
public static string groupingCondition(String s) {
if(s.StartsWith("city") || s.EndsWith("Town"))
return "city";
if(s.StartsWith("country"))
return "country";
if(s.StartsWith("state"))
return "state";
return "unknown";
}
}
You can use LINQ:
var input = new List<string>()
{ "city01", "city01002", "state02",
"state03", "city04", "statebg", "countryqw", "countrypo" };
var output = input.GroupBy(c => string.Join("", c.TakeWhile(d => !char.IsDigit(d))
.Take(4))).ToDictionary(c => c.Key, c => c.ToList());
i suppose you have a list of references you are searching in the list:
var list = new List<string>()
{ "city01", "city01002", "state02",
"state03", "city04", "statebg", "countryqw", "countrypo" };
var tofound = new List<string>() { "city", "state", "country" }; //references to found
var result = new Dictionary<string, List<string>>();
foreach (var f in tofound)
{
result.Add(f, list.FindAll(x => x.StartsWith(f)));
}
In the result, you have the dictionary wanted. If no value are founded for a reference key, the value of key is null
Warning: This answer has a combinatorial expansion and will fail if your original string set is large. For 65 words I gave up after running for a couple of hours.
Using some IEnumerable extension methods to find Distinct sets and to find all possible combinations of sets, you can generate a group of prefixes and then group the original strings by these.
public static class IEnumerableExt {
public static bool IsDistinct<T>(this IEnumerable<T> items) {
var hs = new HashSet<T>();
foreach (var item in items)
if (!hs.Add(item))
return false;
return true;
}
public static bool IsEmpty<T>(this IEnumerable<T> items) => !items.Any();
public static IEnumerable<IEnumerable<T>> AllCombinations<T>(this IEnumerable<T> start) {
IEnumerable<IEnumerable<T>> HelperCombinations(IEnumerable<T> items) {
if (items.IsEmpty())
yield return items;
else {
var head = items.First();
var tail = items.Skip(1);
foreach (var sequence in HelperCombinations(tail)) {
yield return sequence; // Without first
yield return sequence.Prepend(head);
}
}
}
return HelperCombinations(start).Skip(1); // don't return the empty set
}
}
var keys = Enumerable.Range(0, src.Count - 1)
.SelectMany(n1 => Enumerable.Range(n1 + 1, src.Count - n1 - 1).Select(n2 => new { n1, n2 }))
.Select(n1n2 => new { s1 = src[n1n2.n1], s2 = src[n1n2.n2], Dist = src[n1n2.n1].TakeWhile((ch, n) => n < src[n1n2.n2].Length && ch == src[n1n2.n2][n]).Count() })
.SelectMany(s1s2d => new[] { new { s = s1s2d.s1, s1s2d.Dist }, new { s = s1s2d.s2, s1s2d.Dist } })
.Where(sd => sd.Dist > 0)
.GroupBy(sd => sd.s.Substring(0, sd.Dist))
.Select(sdg => sdg.Distinct())
.AllCombinations()
.Where(sdgc => sdgc.Sum(sdg => sdg.Count()) == src.Count)
.Where(sdgc => sdgc.SelectMany(sdg => sdg.Select(sd => sd.s)).IsDistinct())
.OrderByDescending(sdgc => sdgc.Sum(sdg => sdg.First().Dist)).First()
.Select(sdg => sdg.First())
.Select(sd => sd.s.Substring(0, sd.Dist))
.ToList();
var groups = src.GroupBy(s => keys.First(k => s.StartsWith(k)));
I have a nested list called filterTarget.
Example about content:
filterTarget = { Id: 1
InventoryDescription: {Type: "Machine", Code: "1/1", Description: "1", Category: "1", StockCode: "1", …}
InventoryRecordDetails: []
Length: "1"
Life: "04.02.2019"
Location: null
Model: "1" }
The example I want to get the value of Code of InventoryDescription.
I wrote this code for two layers but it's looking dirty and insufficient. And it's not general.
filterTarget = filterTarget
.Where(x => x.GetType()
.GetProperty(fieldval1)
.PropertyType
.GetProperty(fieldval2)
.GetValue(x.GetType()
.GetProperty(fieldval1)
.GetValue(x))
.ToString()?
.ToLower() == deger)
.ToList();
How do I get value from a nested list with reflection and linq?
If you are looking for a linq solution then let would be your friend:
filterTarget = (from f in filterTarget
let temp = f.GetType().GetProperty(fieldval1).GetValue(f)
let temp2 = temp.GetType().GetProperty(fieldval2).GetValue(temp)
where temp2.ToString().ToLower() == deger
select f).ToList();
But personnaly I find it rather unreadable. A normal loop with an appropriate if-condition would be much more maintainable:
public IEnumerable<T> FilterMyList<T>(IEnumerable<T> list, string fieldval1, string fieldval2, string deger)
{
foreach (var element in list)
{
var nesteValue1 = element.GetType().GetProperty(fieldval1).GetValue(element);
var nestedValue2 = nesteValue1.GetType().GetProperty(fieldval2).GetValue(nesteValue1);
if (nestedValue2.ToString().ToLower() == deger)
{
yield return element;
}
}
}
Here is a more general way that uses recursion to dive into your nested object. You need to provide the exact amount of propertynames and it has to match the levels of nestedness:
public IEnumerable<T> FilterMyListRecursive<T>(IEnumerable<T> list, string searchpattern, params string [] propertynames) where T: class
{
foreach (var element in list)
{
if (TryNestedRecursiveDescend(element, searchpattern, propertynames))
{
yield return element;
}
}
}
private bool TryNestedRecursiveDescend<T>(T obj, string searchpattern, params string [] propertynames) where T: class
{
var nestedValue = obj.GetType().GetProperty(propertynames.First()).GetValue(obj);
// if you are at the lowest level that you can check
if (fieldvalues.Length == 1)
{
return nestedValue.ToString().ToLower() == searchpattern;
}
else
{
// recursive call with the remaining propertynames
return TryNestedDescend(nestedValue, searchpattern, propertynames.Skip(1).ToArray());
}
}
filterTarget is my nested List.
field is ordered property string.
filterTarget = (from f in filterTarget
let temp = GetPropertyValue(f, Field)
where temp?.ToString().ToLower() == "deger"
select f).ToList();
private static object GetPropertyValue<T>(T filterTarget, string field)
{
string[] fields = field.Split('.');
object value = filterTarget;
fields?.ToList().ForEach(p =>
{
value = value.GetType().GetProperty(p).GetValue(value);
});
return value;
}
How can I perform a conditional select on a column value, where I have a preference over which value is returned. If I can't find the top choice, I settle on the next, if available, and then if not the next, etc. As it looks right now, it would take 3 total queries. Is there a way to simplify this further?
var myResult = string.Empty;
if (myTable.Where(x => x.ColumnValue == "Three").Any())
{
myResult = "Three"; // Can also be some list.First().Select(x => x.ColumnValue) if that makes it easier;
}
else if (myTable.Where(x => x.ColumnValue == "One").Any())
{
myResult = "One";
}
else if (myTable.Where(x => x.ColumnValue == "Two").Any())
{
myResult = "Two";
}
else
{
myResult = "Four";
}
You could use a string[] for your preferences:
string[] prefs = new[]{ "One", "Two", "Three" };
string myResult = prefs.FirstOrDefault(p => myTable.Any(x => x.ColumnValue == p));
if(myResult == null) myResult = "Four";
Edit Enumerable.Join is a very efficient hash table method, it also needs only one query:
string myResult = prefs.Select((pref, index) => new { pref, index })
.Join(myTable, xPref => xPref.pref, x => x.ColumnValue, (xPref, x) => new { xPref, x })
.OrderBy(x => x.xPref.index)
.Select(x => x.x.ColumnValue)
.DefaultIfEmpty("Four")
.First();
Demo
I wrote an extension method that effectively mirrors Tim Schmelter's answer (was testing this when he posted his update. :-()
public static T PreferredFirst<T>(this IEnumerable<T> data, IEnumerable<T> queryValues, T whenNone)
{
var matched = from d in data
join v in queryValues.Select((value,idx) => new {value, idx}) on d equals v.value
orderby v.idx
select new { d, v.idx };
var found = matched.FirstOrDefault();
return found != null ? found.d : whenNone;
}
// usage:
myResult = myTable.Select(x => x.ColumnValue)
.PreferredFirst(new [] {"Three", "One", "Two"}, "Four");
I've written one that will quit a little more early:
public static T PreferredFirst<T>(this IEnumerable<T> data, IList<T> orderBy, T whenNone)
{
// probably should consider a copy of orderBy if it can vary during runtime
var minIndex = int.MaxValue;
foreach(var d in data)
{
var idx = orderBy.IndexOf(d);
if (idx == 0) return d; // best case; quit now
if (idx > 0 && idx < minIndex) minIndex = idx;
}
// return the best found or "whenNone"
return minIndex == int.MaxValue ? whenNone : orderBy[minIndex];
}
I use a weighted approach in SQL where I assign a weight to each conditional value. The solution would then be found by finding the highest or lowest weight depending on your ordering scheme.
Below would be the equivalent LINQ query. Note that in this example I am assigning a lower weight a higher priority:
void Main()
{
// Assume below list is your dataset
var myList =new List<dynamic>(new []{
new {ColumnKey=1, ColumnValue ="Two"},
new {ColumnKey=2, ColumnValue ="Nine"},
new {ColumnKey=3, ColumnValue ="One"},
new {ColumnKey=4, ColumnValue ="Eight"}});
var result = myList.Select(p => new
{
ColVal = p.ColumnValue,
OrderKey = p.ColumnValue == "Three" ? 1 :
p.ColumnValue == "One" ? 2 :
p.ColumnValue == "Two" ? 3 : 4
}).Where(i=> i.OrderKey != 4)
.OrderBy(i=>i.OrderKey)
.Select(i=> i.ColVal)
.FirstOrDefault();
Console.WriteLine(result ?? "Four");
}
How about something like this:
var results = myTable.GroupBy(x => x.ColumnValue).ToList();
if (results.Contains("Three")) {
myResult = "Three";
} else if (results.Contains("One")) {
myResult = "One";
} else if (results.Contains("Two")) {
myResult = "Two";
} else {
myResult = "Four";
}
my issue is that I have an attribute as 'attribute' coming in from entity framework.
So I retrieve this object which has a list of attribute tags, they are accessible via attribute.AttributeTags. Now I have a asp:TextBox where users can edit, remove and add new tags (comma separated). (On page load I am adding the attribute tags to this TextBox)
After a postback on the page I am returning the user input and splitting it into an array of strings and storing it in a variable called AttributeTags.
Now, I would like to add new tags that are not contained in the original attributes list coming from EF and would like to remove the ones that are contained in attributes but not found in the user input string array AttributeTags.
I am doing something like this:
BusinessObjects.Attribute attribute = db.Attributes.FirstOrDefault(a => a.attribute_id == AttributeID);
string[] AttributeTags = txtAttributeTags.Text.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
foreach (var item in AttributeTags)
{
if (!attribute.AttributeTags.Any(t => t.value == item))
{
AttributeTag tag = new AttributeTag { value = item, timestamp = DateTime.Now };
attribute.AttributeTags.Add(tag);
}
else
{
AttributeTag tag = attribute.AttributeTags.FirstOrDefault(t => t.value == item);
}
}
But I'm sort of stuck here since i'm fairly new to LINQ and EF.
I have two solution of this situations.
First Solution
We can create an ExcepWith method that will allow us to remove all the items in a ICollection<T> that are already in give a IEnumerable<T>. The code for such method follows:
public static int ExceptWith<TItem>
(
this ICollection<TItem> collection,
IEnumerable<TItem> other
)
{
if (ReferenceEquals(collection, null))
{
throw new ArgumentNullException("collection");
}
else if (ReferenceEquals(other, null))
{
throw new ArgumentNullException("other");
}
else
{
int count = 0;
foreach (var item in other)
{
while (collection.Remove(item))
{
count++;
}
}
return count;
}
}
Now you have an string[] with the input of the user, that array is an IEnumerable<string> but not an an ICollection<string>... that is easily solved as follows:
Instead of this:
string[] AttributeTags =
txtAttributeTags.Text.Split
(
new string[] { "," },
StringSplitOptions.RemoveEmptyEntries
);
You do this:
var AttributeTags =
new List<string>
(
txtAttributeTags.Text.Split
(
new string[] { "," },
StringSplitOptions.RemoveEmptyEntries
)
);
Or even this:
var AttributeTags =
txtAttributeTags.Text.Split
(
new string[] { "," },
StringSplitOptions.RemoveEmptyEntries
).ToList();
Now you can do this:
AttriuteTags.ExceptWith(existingTags);
Since the type of attribute.AttributeTag is not IEnumerable<string> you use Select:
AttriuteTags.ExceptWith(attribute.AttributeTag.Select(item => item.value));
And that leaves only the new tags in the list.
Note: this method depends on the implementation of Remove, if you need to do an special comparison, then you are out of luck with this method.
Second Solution
There is another way. You can use the Except from the Enumerable class.
string[] AttributeTags =
txtAttributeTags.Text.Split
(
new string[] { "," },
StringSplitOptions.RemoveEmptyEntries
);
var newTags = AttributeTags.Except(existingTags);
Since the type of attribute.AttributeTag is not IEnumerable<string> you use Select:
string[] AttributeTags =
txtAttributeTags.Text.Split
(
new string[] { "," },
StringSplitOptions.RemoveEmptyEntries
);
var newTags = AttributeTags.Except
(
attribute.AttributeTag.Select(item => item.value)
);
And that puts in newTags, well, the new tags.
Note: If you need to do an special comparison, then you should use the other overload of the method:
string[] AttributeTags =
txtAttributeTags.Text.Split
(
new string[] { "," },
StringSplitOptions.RemoveEmptyEntries
);
var newTags = AttributeTags.Except(attribute.AttributeTag, equalityComparer);
Sadly the equalityComparer is an object of a class that implements IEqualityComparer, meaning that you can't use lambdas there. For that you can add this class:
public class CustomEqualityComparer<T> : IEqualityComparer<T>
{
private Func<T, T, bool> _comparison;
private Func<T, int> _getHashCode;
public CustomEqualityComparer
(
Func<T, T, bool> comparison,
Func<T, int> getHashCode
)
{
if (ReferenceEquals(comparison, null))
{
throw new ArgumentNullException("comparison");
}
else if (ReferenceEquals(getHashCode, null))
{
throw new ArgumentNullException("getHashCode");
}
else
{
_comparison = comparison;
_getHashCode = getHashCode;
}
}
public bool Equals(T x, T y)
{
return _comparison.Invoke(x, y);
}
public int GetHashCode(T obj)
{
return _getHashCode.Invoke(obj);
}
}
And now invoke like this (for example):
string[] AttributeTags =
txtAttributeTags.Text.Split
(
new string[] { "," },
StringSplitOptions.RemoveEmptyEntries
);
var newTags = AttributeTags.Except
(
existingTags,
new CustomEqualityComparer<string>
(
(a, b) => 1, //your custom comparison here
str => str.GetHashCode()
)
);
Since the type of attribute.AttributeTag is not IEnumerable<string> you use Select:
string[] AttributeTags =
txtAttributeTags.Text.Split
(
new string[] { "," },
StringSplitOptions.RemoveEmptyEntries
);
var newTags = AttributeTags.Except
(
attribute.AttributeTag.Select(item => item.value),
new CustomEqualityComparer<string>
(
(a, b) => 1, //your custom comparison here
str => str.GetHashCode()
)
);
Adding the new tags
Now that you have the new tags, let's say in newTags, you can iterate it to add the new tags:
var now = DateTime.Now;
foreach (var item in newTags)
{
AttributeTag tag = new AttributeTag { value = item, timestamp = now };
attribute.AttributeTags.Add(tag);
}
Comparing the Solutions
What's the difference of these methods?
The first requires less memory
The first requires to define a new method.
The first doesn't allow for a custom IEqualityComparer<T>
The second allows for deferred execution.
The second uses (not needed) a helper class.
A simplified example of how to do what you want.
var fromDB = new List<string>() { "a", "b", "c", "d", "e" };
var userInput = new List<string>() { "c", "d", "e", "f", "g" };
var result = fromDB.Join(userInput, x => x, y => y, (x, y) => x).Union(userInput);
Now all you have to do is replace the database contents with the results.
This problem can be solved very elegantly with an Iesi.Collections
There are several implementations of it, here is one: Set Collections
ListSet set1 = new ListSet(new [] {"1","2","8"});
ListSet set2 = new ListSet(new [] {"8","16","32"});
var union = set1 | set2; // "1","2","8","16","32"
var intersect = set1 & set2; // "8"
var diff = set1 ^ set2; // "1","2","16","32"
var minus = set1 - set2; // "1","2"
Here is the code that I tested. There are a lot of ways of saving in entity framework.
Note: please make sure not to modify/remove items while iterating a collection.
<asp:TextBox ID="txtAttributeTags" runat="server" />
<asp:Button runat="server" ID="SubmitButton" OnClick="SubmitButton_Click"
Text="Submit" />
public const int AttributeID = 1;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
using (var db = new AttributeEntities())
{
var tags = db.AttributeTags
.Where(a => a.attribute_id == AttributeID)
.Select(a => a.value);
txtAttributeTags.Text = string.Join(",", tags);
}
}
}
protected void SubmitButton_Click(object sender, EventArgs e)
{
using (var db = new AttributeEntities())
{
string[] newTags = txtAttributeTags.Text.Split(new[] {","},
StringSplitOptions.RemoveEmptyEntries);
var oldTags = db.AttributeTags.Where(t => t.attribute_id == AttributeID);
foreach (var tag in oldTags.Where(o => !newTags.Contains(o.value)))
db.AttributeTags.DeleteObject(tag);
foreach (var tag in newTags.Where(n => !oldTags.Any(o => o.value == n)))
db.AttributeTags.AddObject(new AttributeTag
{
attribute_id = AttributeID, value = tag, timestamp = DateTime.Now
});
db.SaveChanges();
}
}
}
us the Remove method on the Attributes property of the db object then save changes
db.Attributes.Remove( object );
Then Save changes to the db object.
This should work if I am assuming correctly that your db object is the connected object in the EF.
I cannot do a full test, but something along these lines should do:
BusinessObjects.Attribute attribute = db.Attributes.FirstOrDefault(a => a.attribute_id == AttributeID);
string[] AttributeTags = txtAttributeTags.Text.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
foreach (var item in from a in AttributeTags
where attribute.AttributeTags.Any(t => t.value == a)
select new AttributeTag
{
value = item,
timestamp = DateTime.Now
})
attribute.AttributeTags.Add(item);
foreach (var item in from a in attribute.AttributeTags
where AttributeTags.Any(t => t == a.value)
select a)
attribute.AttributeTags.Remove(item);
db.SaveChanges();
Here I have a simple example to find an item in a list of strings. Normally I use a for loop or anonymous delegate to do it like this:
int GetItemIndex(string search)
{
int found = -1;
if ( _list != null )
{
foreach (string item in _list) // _list is an instance of List<string>
{
found++;
if ( string.Equals(search, item) )
{
break;
}
}
/* Use an anonymous delegate
string foundItem = _list.Find( delegate(string item) {
found++;
return string.Equals(search, item);
});
*/
}
return found;
}
LINQ is new for me. Can I use LINQ to find an item in the list? If it is possible, how?
There are a few ways (note that this is not a complete list).
Single will return a single result, but will throw an exception if it finds none or more than one (which may or may not be what you want):
string search = "lookforme";
List<string> myList = new List<string>();
string result = myList.Single(s => s == search);
Note that SingleOrDefault() will behave the same, except it will return null for reference types, or the default value for value types, instead of throwing an exception.
Where will return all items which match your criteria, so you may get an IEnumerable<string> with one element:
IEnumerable<string> results = myList.Where(s => s == search);
First will return the first item which matches your criteria:
string result = myList.First(s => s == search);
Note that FirstOrDefault() will behave the same, except it will return null for reference types, or the default value for value types, instead of throwing an exception.
If you want the index of the element, this will do it:
int index = list.Select((item, i) => new { Item = item, Index = i })
.First(x => x.Item == search).Index;
// or
var tagged = list.Select((item, i) => new { Item = item, Index = i });
int index = (from pair in tagged
where pair.Item == search
select pair.Index).First();
You can't get rid of the lambda in the first pass.
Note that this will throw if the item doesn't exist. This solves the problem by resorting to nullable ints:
var tagged = list.Select((item, i) => new { Item = item, Index = (int?)i });
int? index = (from pair in tagged
where pair.Item == search
select pair.Index).FirstOrDefault();
If you want the item:
// Throws if not found
var item = list.First(item => item == search);
// or
var item = (from item in list
where item == search
select item).First();
// Null if not found
var item = list.FirstOrDefault(item => item == search);
// or
var item = (from item in list
where item == search
select item).FirstOrDefault();
If you want to count the number of items that match:
int count = list.Count(item => item == search);
// or
int count = (from item in list
where item == search
select item).Count();
If you want all the items that match:
var items = list.Where(item => item == search);
// or
var items = from item in list
where item == search
select item;
And don't forget to check the list for null in any of these cases.
Or use (list ?? Enumerable.Empty<string>()) instead of list.
Do you want the item in the list or the actual item itself (would assume the item itself).
Here are a bunch of options for you:
string result = _list.First(s => s == search);
string result = (from s in _list
where s == search
select s).Single();
string result = _list.Find(search);
int result = _list.IndexOf(search);
If it really is a List<string> you don't need LINQ, just use:
int GetItemIndex(string search)
{
return _list == null ? -1 : _list.IndexOf(search);
}
If you are looking for the item itself, try:
string GetItem(string search)
{
return _list == null ? null : _list.FirstOrDefault(s => s.Equals(search));
}
This method is easier and safer
var lOrders = new List<string>();
bool insertOrderNew = lOrders.Find(r => r == "1234") == null ? true : false
How about IndexOf?
Searches for the specified object and returns the index of the first occurrence within the list
For example
> var boys = new List<string>{"Harry", "Ron", "Neville"};
> boys.IndexOf("Neville")
2
> boys[2] == "Neville"
True
Note that it returns -1 if the value doesn't occur in the list
> boys.IndexOf("Hermione")
-1
This will help you in getting the first or default value in your LINQ List search
var results = _List.Where(item => item == search).FirstOrDefault();
This search will find the first or default value, which it will return.
I used to use a Dictionary which is some sort of an indexed list which will give me exactly what I want when I want it.
Dictionary<string, int> margins = new Dictionary<string, int>();
margins.Add("left", 10);
margins.Add("right", 10);
margins.Add("top", 20);
margins.Add("bottom", 30);
Whenever I wish to access my margins values, for instance, I address my dictionary:
int xStartPos = margins["left"];
int xLimitPos = margins["right"];
int yStartPos = margins["top"];
int yLimitPos = margins["bottom"];
So, depending on what you're doing, a dictionary can be useful.
If we need to find an element from the list, then we can use the Find and FindAll extensions method, but there is a slight difference between them. Here is an example.
List<int> items = new List<int>() { 10, 9, 8, 4, 8, 7, 8 };
// It will return only one 8 as Find returns only the first occurrence of matched elements.
var result = items.Find(ls => ls == 8);
// this will returns three {8,8,8} as FindAll returns all the matched elements.
var result1 = items.FindAll(ls => ls == 8);
Here is one way to rewrite your method to use LINQ:
public static int GetItemIndex(string search)
{
List<string> _list = new List<string>() { "one", "two", "three" };
var result = _list.Select((Value, Index) => new { Value, Index })
.SingleOrDefault(l => l.Value == search);
return result == null ? -1 : result.Index;
}
Thus, calling it with
GetItemIndex("two") will return 1,
and
GetItemIndex("notthere") will return -1.
Reference: linqsamples.com
Try this code:
return context.EntitytableName.AsEnumerable().Find(p => p.LoginID.Equals(loginID) && p.Password.Equals(password)).Select(p => new ModelTableName{ FirstName = p.FirstName, UserID = p.UserID });
You can use FirstOfDefault with the Where LINQ extension to get a MessageAction class from the IEnumerable. Reme
var action = Message.Actions.Where(e => e.targetByName == className).FirstOrDefault<MessageAction>();
where
List<MessageAction> Actions { get; set; }
One more way to check the existence of an element in a List<string>:
var result = myList.Exists(users => users.Equals("Vijai"))
You want to search an object in object list.
This will help you in getting the first or default value in your Linq List search.
var item = list.FirstOrDefault(items => items.Reference == ent.BackToBackExternalReferenceId);
or
var item = (from items in list
where items.Reference == ent.BackToBackExternalReferenceId
select items).FirstOrDefault();