如何在Collection中找到一个对象,其中Collection具有相同类型的子集合?

时间:2016-02-25 21:11:06

标签: c# collections

如果我有一个Collection<T>,并且每个T对象都可以有一个子Collection<T>以及一个Collection<T2>,那么查找对象的最佳方法是怎样的? T2,我知道string name对象的T2,我有一个Collection<T>

3 个答案:

答案 0 :(得分:0)

递归搜索实例级别T2集合和子T集合,直到找到匹配项。

public T2 Find(T primaryObject, string searchValue)
{
    var secondaryObject = primaryObject.T2Collection.SingleOrDefault(x => x.Name == searchValue)
    if (secondaryObject != null)
        return secondaryObject;

    foreach (var childObject in primaryObject.T1Collection)
    {
        secondaryObject = Find(childObject, searchValue);
        if (secondaryObject != null)
            return secondaryObject;
    }

    return null;
}

答案 1 :(得分:0)

您需要一种递归方法来搜索与搜索到的值匹配的所有T2:

public class Program
{
    private static IEnumerable<Bar> Find( Foo foo, String name )
    {
        foreach ( var x in foo.Bars.Where( x => x.Name == name ) )
            yield return x;

        var bars = foo.Foos?.SelectMany( x => Find( x, name ) ) ?? new Bar[0];
        foreach ( var y in  bars)
            yield return y;
    }

    public static void Main( String[] args )
    {
        var foo = new Foo
        {
            Bars = new List<Bar>
            {
                new Bar { Name = "n1" },
                new Bar { Name = "n2" },
                new Bar { Name = "n3" },
                new Bar { Name = "n4" }
            },
            Foos = new List<Foo>
            {
                new Foo
                {
                    Bars = new List<Bar>
                    {
                        new Bar { Name = "n1" },
                        new Bar { Name = "n2" },
                        new Bar { Name = "n3" },
                        new Bar { Name = "n4" }
                    },
                    Foos = new List<Foo>
                    {
                        new Foo
                        {
                            Bars = new List<Bar>
                            {
                                new Bar { Name = "n1" },
                                new Bar { Name = "n2" },
                                new Bar { Name = "n3" },
                                new Bar { Name = "n4" }
                            }
                        }
                    }
                },
                new Foo
                {
                    Bars = new List<Bar>
                    {
                        new Bar { Name = "n1" },
                        new Bar { Name = "n2" },
                        new Bar { Name = "n3" },
                        new Bar { Name = "n4" }
                    }
                }
            }
        };

        foreach ( var x in Find( foo, "n1" ) )
            Console.WriteLine( x.Name );

        Console.ReadLine();
    }
}

public class Foo
{
    #region Properties

    public IEnumerable<Foo> Foos { get; set; }
    public IEnumerable<Bar> Bars { get; set; }

    #endregion
}

public class Bar
{
    #region Properties

    public String Name { get; set; }

    #endregion
}

答案 2 :(得分:0)

通常可以使用Reactive Extension代替递归函数:

using System.Reactive.Linq;
public class T2
{
    public string Name;
}

public class T
{
    public IEnumerable<T2> t2Collection;
    public IEnumerable<T> tCollection;
}

public T2 Find(IEnumerable<T> primaryCollection, string searchValue)
{
    T2 result = null;
    Observable.Generate(
            new 
            {
                currentCollection = primaryCollection, 
                searchedT2 = default(T2) 
            },
            state => state.searchedT2 == default(T2),
            state => new
            {
            currentCollection = state.currentCollection.SelectMany(t => t.tCollection),
            searchedT2 = state.currentCollection.SelectMany(t => t.t2Collection).FirstOrDefault(t2 => t2.Name == searchValue)
            },
            state => state.searchedT2
            ).Subscribe(t2=>result=t2);

    return result;
    }