【问题标题】:Finding Tuple in list with three items matched在列表中查找匹配三个项目的元组
【发布时间】:2012-12-30 01:57:29
【问题描述】:

我需要在包含三个给定项目的List 中获取Tuple<string,string,string,string> 的索引,但第四个是什么并不重要。例如:

Listoftuples.IndexOf(new Tuple<string,string,string,string>("value1","value2","value3","this value does not matter"))

在索引方面是否有通配符,或者有其他方法可以解决这个问题?

【问题讨论】:

    标签: c# string indexing tuples wildcard


    【解决方案1】:
    int index = Listoftuples.FindIndex(t => t.Item1 == "value1" && t.Item2 == "value2" && t.Item3 == "value3");
    

    您可能想要创建一个函数来创建谓词:

    Func<Tuple<string,string,string,string>, bool> CreateMatcher(string first, string second, string third)
    {
        return t => t.Item1 == first && t.Item2 == second && t.Item3 == third;
    }
    

    那么你可以使用

    int index = Listoftuples.FindIndex(CreateMatcher("value1", "value2", "value3"));
    

    【讨论】:

    • @flq - 谢谢,我一直在寻找,但错过了。
    【解决方案2】:

    没那么复杂。这是一个通用的辅助方法:

    public static int IndexOf<TSource, TKey>(this IEnumerable<TSource> source, TKey key
        , Func<TSource, TKey> selector)
    {
        int i = 0;
        foreach (var item in source)
        {
            if (object.Equals(selector(item), key))
                return i;
            i++;
        }
    
        return -1;
    }
    

    现在您有了一个带有选择器的IndexOf 方法,它就像这样简单:

    list.IndexOf(Tuple.Create("value1", "value2", "value3")
        , item => Tuple.Create(item.Item1, item.Item2, item.Item3));
    

    请注意,如果您想让IndexOf 方法更通用,可以将IComparer&lt;TKey&gt; 作为可选参数添加到该方法中。

    【讨论】:

      【解决方案3】:

      虽然 Oded 的回答是(是)正确的,但 Linq 有一个内置的方法来做几乎所有基于列表的事情,所以你不必自己动手。

      var myElement = (Listoftuples.Select((x,i)=>new {Index = i, 
                                Element = Tuple.Create(x.Item1, x.Item2, x.Item3})
                            .FirstOrDefault(a=>a.Element == TupleToSearchFor);
      var myIndex = myElement == null ? -1 : myElement.Index;
                 
      

      分解:

      • Select() 方法有一个重载,它接受一个带有两个参数的 lambda;源可枚举的当前元素源中该元素的“索引”(请理解这仅对我们有效,因为我们不会更改原始列表中任何元素的顺序;如果我们首先对其进行了排序,Listoftuples 和传递给 Select() 的元素之间的索引不匹配。

        然后我们使用这个方法来生成匿名类型的元素,它为我们做了两件事;首先,我们可以将 Tuple 更改为三个值的 Tuple(每个源 Tuple 的前三个,这是我们关心的),其次,我们可以相对轻松地“固定”原始元素的索引列表供以后参考。

      • FirstOrDefault() 遍历 Select() 调用的结果,直到它找到一个元组与我们正在搜索的元素匹配的元素(或者它没有找到任何东西,在这种情况下它返回 null)。

      • 因为 FirstOrDefault() 可能返回 null,我们需要检查它。有很多方法可以做到这一点;我输入的那个,用三元语句,足够简单易懂。

      最后,myIndex 将具有 Listoftuples 的第一个匹配元素的索引,或 -1,这意味着 Listoftuples 的所有元素都与您搜索的元素不匹配。

      【讨论】:

        猜你喜欢
        • 2020-07-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多