如何在不循环遍历列表的情况下找到项目的索引?
目前这看起来不太好 - 为了获取索引而在列表中搜索相同的项目两次:
var oProp = something;
int theThingIActuallyAmInterestedIn = myList.IndexOf(myList.Single(i => i.Prop == oProp));
那么来看一下List.FindIndex 方法如何使用:
int index = myList.FindIndex(a => a.Prop == oProp);
该方法执行线性搜索;因此,此方法是一个O(n)操作,其中n为Count。
如果未找到该项,则返回-1。
int index
怎么样? - Dylan Czenski对于简单类型,你可以使用"IndexOf":
List<string> arr = new List<string>();
arr.Add("aaa");
arr.Add("bbb");
arr.Add("ccc");
int i = arr.IndexOf("bbb"); // Returns 1.
List <string>
,那么这是正确的方法,但是对于复杂对象的列表来说,这并不可行。 - Ruslan编辑:如果你仅使用List<>
,并且只需要索引,则List.FindIndex
确实是最佳方法。我将保留此答案供那些需要其他内容(例如在任何IEnumerable<>
之上)的人使用。
使用带有索引的谓词的Select
重载,这样你就可以将列表转换为(索引,值)对:
var pair = myList.Select((Value, Index) => new { Value, Index })
.Single(p => p.Value.Prop == oProp);
然后:
Console.WriteLine("Index:{0}; Value: {1}", pair.Index, pair.Value);
或者,如果你只需要索引,并且在多个地方使用它,你可以轻松编写自己的扩展方法,就像Where
一样,但是它返回与谓词匹配的项的索引,而不是原始项。
Single()
操作遍历该序列并找到与谓词匹配的单个项。更多详情请阅读我的edulinq博客系列:http://codeblog.jonskeet.uk/category/edulinq/ - Jon Skeet如果您不想使用LINQ,则:
int index;
for (int i = 0; i < myList.Count; i++)
{
if (myList[i].Prop == oProp)
{
index = i;
break;
}
}
这种方式只会对列表进行一次迭代。
FindIndex
是一样的吗? - Paul C在列表中查找任意字符串值的索引的简单解决方案。
这里是一个字符串列表的代码:
int indexOfValue = myList.FindIndex(a => a.Contains("insert value from list"));
查找列表中任何整数值的索引的简单解决方案。
这是一个整数列表的代码:
int indexOfNumber = myList.IndexOf(/* insert number from list */);
如果有人想了解 Array
版本,可以这样做:
int i = Array.FindIndex(yourArray, x => x == itemYouWant);
public static class EnumerableExtensions
{
/// <summary>
/// Searches for an element that matches the conditions defined by the specified predicate,
/// and returns the zero-based index of the first occurrence within the entire <see cref="IEnumerable{T}"/>.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list">The list.</param>
/// <param name="predicate">The predicate.</param>
/// <returns>
/// The zero-based index of the first occurrence of an element that matches the conditions defined by <paramref name="predicate"/>, if found; otherwise it'll throw.
/// </returns>
public static int FindIndex<T>(this IEnumerable<T> list, Func<T, bool> predicate)
{
var idx = list.Select((value, index) => new {value, index}).Where(x => predicate(x.value)).Select(x => x.index).First();
return idx;
}
}
享受。
这都很好 - 但是如果您想将现有元素选择为默认值怎么办?在我的问题中,没有“--选择一个值--”选项。
这是我的代码 - 如果您不想检查没有结果,您可以将其变成一行...
private void LoadCombo(ComboBox cb, string itemType, string defVal = "")
{
cb.DisplayMember = "Name";
cb.ValueMember = "ItemCode";
cb.DataSource = db.Items.Where(q => q.ItemTypeId == itemType).ToList();
if (!string.IsNullOrEmpty(defVal))
{
var i = ((List<GCC_Pricing.Models.Item>)cb.DataSource).FindIndex(q => q.ItemCode == defVal);
if (i>=0) cb.SelectedIndex = i;
}
}
List<YourObject> listObj = new List<YourObject>();
var obj = new YourObject();
int idx = listObj.IndexOf(obj);