我有对象数组,我想在这个数组中找到某个特定对象的索引:
int ix = Array.IndexOf(products, products.Where(item => item != null && item.Id == "xxx").FirstOrDefault());
Id =“xxx”的项目不存在,但ix结果为1。 所以,我猜int的默认值是1.我怎么知道1是属于第一项还是默认值?如果我可以将默认值设置为-1,那就太好了。
最后我用findIndex方法完成了它,但是想知道如何使用indexOf方法。
答案 0 :(得分:4)
所以你有一个问题的两个部分。首先,您想要找到一个产品:
var product = products.FirstOrDefault(item => item != null && item.Id == "xxx");
找到该产品后,您希望在products
集合中找到其索引:
int index = Array.IndexOf(products, product);
你使用FirstOrDefault()
进入中途。如果产品带有Id" xxx"如果不存在,product
将为null
。因此,您可以检查并跳过IndexOf()
null
:
if (product == null)
{
return -1;
}
else
{
return Array.IndexOf(products, product);
}
您当前的代码返回1,这意味着products[1]
为null
。
答案 1 :(得分:1)
Per Microsoft:
有时,如果集合不包含任何元素,则默认值(TSource)不是您要使用的默认值。您可以使用DefaultIfEmpty(IEnumerable,TSource)方法指定在集合为空时要使用的默认值,而不是检查结果是否包含不需要的默认值,然后根据需要进行更改。然后,调用First(IEnumerable)来获取第一个元素。
但是,我不太确定你的问题。您的代码在语法上不正确(您错过了')'在某处),但你似乎在Where()之后调用了FirstOrDefault()。这将返回一个元素或null。既然你说了一个id为#34; xxx"它不存在,它将检查数组中的null索引。 indexOf的默认值是(再次,每个Microsoft)"数组的下限减1。"这应该返回-1(我希望)而不是1。
结论:更好地查看代码并了解实际情况。将这个linq语句分成两个不同的部分。
var item = products.Where(item => item != null && item.Id == "xxx").FirstOrDefault();
int ix = Array.IndexOf(products, item);
然后单步执行代码以检查所有内容的值。我相信你会发现你的问题,但它不会成为你的期望。
答案 2 :(得分:1)
First或default返回第一个元素(在这种情况下,在where条件中找到的第一个项目)或者,默认值。
如果符合条件(第一个符合条件的对象),这将返回一个OBJECT。
但是,如果不满足条件,它将返回null (OBJECT的默认值), 所以你的代码会试图找到indexOf(products,null)..这将是一个NullReferenceException。
firstOrDefault正在数组内的OBJECT类型下完成他的工作。
在此之后,结果将作为参数传递给方法indexOf。
“indexOf”将返回“where”条件下第一个对象的索引。
如果未找到,indexOf将返回-1。
顺便说一下,你错过了一个括号。
答案 3 :(得分:1)
如果你想在一个结构上调用FirstOrDefault但默认值与有效结果相同,那么你可以做一件事:
(我不会使用您的代码,因为缺失的括号无法知道您的目标是什么)
myCollection.Where(myCondition).Cast<int?>().FirstOrDefault();
这样,0
将是第一个正确的值,null
意味着没有正确的值。