Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用LINQ查询获取索引值的集合_C#_.net_Arrays_Linq_Indexof - Fatal编程技术网

C# 使用LINQ查询获取索引值的集合

C# 使用LINQ查询获取索引值的集合,c#,.net,arrays,linq,indexof,C#,.net,Arrays,Linq,Indexof,有更好的方法吗 string[] s = {"zero", "one", "two", "three", "four", "five"}; var x = s .Select((a,i) => new {Value = a, Index = i}) .Where(b => b.Value.StartsWith("t")) .Select(c => c.Index); i、 e.我正在寻找一种更有效或更优雅的方法来获得符合标准的项目位置。对我来说似乎很好。您可以通过将“选择

有更好的方法吗

string[] s = {"zero", "one", "two", "three", "four", "five"};

var x = 
s
.Select((a,i) => new {Value = a, Index = i})
.Where(b => b.Value.StartsWith("t"))
.Select(c => c.Index);

i、 e.我正在寻找一种更有效或更优雅的方法来获得符合标准的项目位置。

对我来说似乎很好。您可以通过将“选择”更改为:

.Select((Value, Index) => new {Value, Index})

如果你只是用这个例子来学习LINQ,请忽略这篇文章


我不清楚LINQ是否是实现这一点的最佳方式。下面的代码似乎更有效,因为不需要创建新的匿名类型。诚然,您的示例可能是人为设计的,并且该技术在不同的上下文中可能更有用,例如在数据结构中,它可以利用值索引,但下面的代码相当直截了当,可以理解(无需思考),并且可以说更有效

string[] s = {"zero", "one", "two", "three", "four", "five"};
List<int> matchingIndices = new List<int>();

for (int i = 0; i < s.Length; ++i) 
{
   if (s[i].StartWith("t"))
   {
      matchingIndices.Add(i);
   }
}
string[]s={“零”、“一”、“二”、“三”、“四”、“五”};
List matchingIndices=新列表();
对于(int i=0;i
您可以轻松添加自己的扩展方法:

public static IEnumerable<int> IndexesWhere<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
    int index=0;
    foreach (T element in source)
    {
        if (predicate(element))
        {
            yield return index;
        }
        index++;
    }
}

集合列表中还有FindIndex方法,您可以为其创建一个delete方法,该方法可以从集合中返回索引。您可以参考msdn中的以下链接。

这个怎么样?它类似于原始海报,但我首先选择索引,然后构建一个符合标准的集合

var x = s.Select((a, i) => i).Where(i => s[i].StartsWith("t"));

这比其他一些答案的效率要低一些,因为列表被完全迭代了两次。

我与一位同事讨论了这个有趣的问题,起初我认为JonSkeet的解决方案很好,但我的同事指出了一个问题,即如果函数是
IEnumerable
的扩展,然后可以在集合实现它的地方使用它


对于数组,可以肯定地说,使用
foreach
生成的顺序将得到尊重(即
foreach
将从第一个迭代到最后一个),但对于其他集合(列表、词典等),
foreach
不一定反映“条目顺序”。然而,它的功能是存在的,它可能会产生误导

最后,我得到了与tvanfosson的答案类似的结果,但作为阵列的一种扩展方法:

public static int[] GetIndexes<T>(this T[]source, Func<T, bool> predicate)
{
    List<int> matchingIndexes = new List<int>();

    for (int i = 0; i < source.Length; ++i) 
    {
        if (predicate(source[i]))
        {
            matchingIndexes.Add(i);
        }
    }
    return matchingIndexes.ToArray();
}
公共静态int[]GetIndexes(此T[]源,Func谓词)
{
列表匹配索引=新列表();
对于(int i=0;i

这是希望
列表。ToArray
将尊重上一次操作的顺序…

谢谢-我不知道你能做到这一点-我认为你必须重新分配。它被称为“投影初始值设定项”-它基本上接受表达式中最后一个子表达式(必须是字段或属性)并将其用作名称。所以你可以做x.GetFoo().Bar,这相当于Bar=x.GetFoo().Bar。谢谢你的回答。我同意这样会更有效率。正如您所猜测的,这是一个更复杂的简化版本,在这种特殊情况下,必须在LINQ中“完成”。而确切的代码只有在您使用列表而不是任意IEnumerable时才起作用。否则,您必须使用foreach和一个单独的局部变量。“但是函数存在,并且可能会产生误导。”-但对于使用索引的任何其他LINQ方法,例如
.Select((项,索引)也是如此=>
。我认为只要你理解你得到了什么,Jon的函数就不一定有什么问题。@Rup从那以后,我在LINQ和IEnumerable接口方面积累了更多的经验。我同意如果你知道你在做什么,并且定义了函数,就不会有意外。一个潜在的危险是e从使用
AsParallel
生成的IEnumerable中获取索引。这些索引将反映集合的生成状态,但再次生成几乎可以保证得到不同的结果。索引将引用不存在的内容。在团队工作中(或稍后重用该函数),如果这种行为不清楚,你会有麻烦的。不过,我仍然认为,除非你修改集合,否则顺序不太可能改变,除非对结构有意义,否则你不应该使用索引。但我没有考虑使用AsParallel-neat,谢谢。
public static int[] GetIndexes<T>(this T[]source, Func<T, bool> predicate)
{
    List<int> matchingIndexes = new List<int>();

    for (int i = 0; i < source.Length; ++i) 
    {
        if (predicate(source[i]))
        {
            matchingIndexes.Add(i);
        }
    }
    return matchingIndexes.ToArray();
}