C# 如何在列表中使用IndexOf?
如果我申报一份清单C# 如何在列表中使用IndexOf?,c#,list,C#,List,如果我申报一份清单 List<object[]> People = new List<object[]>(); 有没有办法找到这样一个人的索引 People.IndexOf(new object[] {"Sam", 18}); 我试着像上面那样做,但它返回-1 用我自己的蹩脚方法解决了这个问题,创建了一个扩展方法,它接受一个字符串参数并在列表中循环,直到它与一个匹配,然后返回那个索引 public static int OIndexOf(this
List<object[]> People = new List<object[]>();
有没有办法找到这样一个人的索引
People.IndexOf(new object[] {"Sam", 18});
我试着像上面那样做,但它返回-1
用我自己的蹩脚方法解决了这个问题,创建了一个扩展方法,它接受一个字符串参数并在列表中循环,直到它与一个匹配,然后返回那个索引
public static int OIndexOf(this List<object[]> List, string Check)
{
for (int I = 0; I < List.Count; I++)
{
if ((string)List[I][0] == Check)
return I;
}
return -1;
}
一般来说,需要一个具体的类型来实现这一点,比如Person对象或int值 这种情况的原因是您的类型必须实现.Equals方法。它不适用于对象对象,因为对象的.Equals方法比较引用,而不是值,并且您的比较将始终返回false,除非您的代码中有原始对象,而不是创建新对象进行比较的情况 从: 此方法搜索一维数组的所有元素以查找 价值要确定数组中是否存在值,该方法将执行 通过调用每个元素的Equals方法直到 它找到了匹配项。这意味着如果元素覆盖 方法,该重写被调用 因此,您需要一个具有Equals覆盖的Person对象。也就是说:
public class Person
{
public string Name { get; set; }
public override bool Equals(Person other)
{
return Name.Equals(other.Name);
}
}
如果要比较一个人物数组,则需要另一个封装人物数组的类型,以及一个Equals方法来检查数组中每个人与另一个数组中每个人的相等性。如果有对要查找的实际数组的引用,则IndexOf将按您希望的方式工作。但是您正在创建一个新数组,因此它无法工作 执行您想要的操作的最简单方法是使用FindIndex: People.FindIndexp=>p[0]==Sam&&p[1]==18 要以相同的索引与变量中的整个数组进行比较,请使用LINQ的SequenceEqual var arr=新对象[]{Sam,18}; People.FindIndexp=>arr.SequenceEqualp;
如果你真的想做,你必须自己做 示例:创建新函数:
int NewIndexOf(people, item)
{
int index = 0;
if(people.length) < 2
return -1;
foreach(var p in people)
{
p[0].Equals("Sam") && p[1].Equals(18)
return index;
++index;
}
return -1;
}
IndexOf对给定的类型对象使用默认的相等比较器,在您的例子中就是这样
比较器引用。您有两个新的-两个不同的引用,这反过来意味着
这两种情况都被认为是不平等的。要解决此问题,您可以:
实现您自己的类:
public class Person : IEquatable<Person> {
public Person(string name, int age) {
if (null == name)
throw new ArgumentNullException(nameof(name));
if (age < 0)
throw new ArgumentOutOfRangeException(nameof(age));
Name = name;
Age = age;
}
public String Name {get;}
public int Age {get;}
public bool Equals(Person other) =>
other != null && other.Name == Name && other.Age == Age;
public override bool Equals(Object o) => Equals(o as Person);
public override int GetHashCode() => Name.GetHashCode() ^ Age;
}
想想“新”这个词是什么意思。我想你肯定是在使用面向对象的对象来帮助你解决这个问题。为什么要使用对象数组来描述具有结构化模式的实体?用每个字段创建一个类并覆盖相等值。感谢您指出我的疏忽,尽管我的原意是要求一个类似的选项。在我看来,这个答案完全没有抓住问题的重点。首先,只要对象覆盖的实际运行时类型等于,列表就可以正常工作。不需要具体的非对象类型。第二,OP的例子是一个列表,这意味着这里真正的问题是数组不实现值相等,因此必须实现自定义索引,例如扩展方法,它知道如何比较数组的值相等。请阅读我答案的最后一句。是的,那么?你答案的第一部分完全错了。或者至少,你无法准确地表达自己,无法传达真正需要传达的信息。是的,数组的不覆盖等于,但你的帖子似乎没有讨论这个,或者根本没有讨论覆盖你自己说的;您可以使用object,但运行时类型必须是实现Equals的类型,这意味着您仍然需要一个具体的类型,除非您可以想出一种方法在类中实现Equals而不实际创建类。p[0]附近是否缺少EqualsSam?比如说如果?你测试/编译过这个吗?
public class Person : IEquatable<Person> {
public Person(string name, int age) {
if (null == name)
throw new ArgumentNullException(nameof(name));
if (age < 0)
throw new ArgumentOutOfRangeException(nameof(age));
Name = name;
Age = age;
}
public String Name {get;}
public int Age {get;}
public bool Equals(Person other) =>
other != null && other.Name == Name && other.Age == Age;
public override bool Equals(Object o) => Equals(o as Person);
public override int GetHashCode() => Name.GetHashCode() ^ Age;
}
List<Person> People = new List<Person>();
People.Add(new Person("Sam", 18));
// Now .NET knows how to compare Person instances
int index = People.IndexOf(new Person("Sam", 18));
List<object[]> People = new List<object[]>();
...
var index = People
.Select((v, i) => new { v, i })
.FirstOrDefault(pair => pair.v.SequenceEqual(new object[] { "Sam", 18 }))
?.i ?? -1;