1

I have a list of strings, and in this list of strings there might be references to a list of other strings. For instance, suppose the list is like so: [a.txt, b.txt, c.more], and when I iterate over the list I'd like to lookup in a dictionary: {{'c.more', [c.txt, d.txt]}} so that the resulting list is [a.txt, b.txt, c.txt, d.txt] as a result of looking up c.more in the dictionary.

What I have at this point is something like this:

var dict = new Dictionary<string,List<string>>
{
    {"c.more", new List<string> { "c.txt", "d.txt" } }
}

list.SelectMany(
    f =>
    f.EndsWith(".more")
       ? Expand(f)
       : Include(f, dict))

Where Expand and Include do this:

public IEnumerable<string> Include(string f) { yield return f; }

public IEnumerable<string> Expand(string f, Dictionary<string,List<string>> dict) {
    return dict.ContainsKey(f) ? dict[f] : new List<string>();
}

I could simply return a new List<string> { f } in the first half of the ternary and the result of doing the lookup in the second half, but I want to later handle a recursive lookup so I'm farming out the Expand. Right now I'm not really concerned about memory usage, but I felt like there might be some other way of doing what I'm after that I haven't seen yet.

Is there a better approach to expand a list with more lists?

4

1 に答える 1

1

もう答えは必要ないかもしれませんが、それでも試してみたいと思います。

オプションは、から継承する独自のクラスを作成することIEnumerableです。次のようにします。

public class LookupList : IEnumerable<string>
{
    private readonly IEnumerable<string> _source;
    private Dictionary<string, List<string>> _referenceDic;

    public LookupList(IEnumerable<string> source, Dictionary<string, List<string>> referenceDic)
    {
        _source = source;
        _referenceDic = referenceDic;
    }

    public IEnumerator<string> GetEnumerator()
    {
        foreach (string item in _source)
        {
            //check if it's in the ref dictionary, if yes: return only sub items, if no: return the item
            if (_referenceDic.Keys.Contains(item))
            {
                foreach (string dicItem in _referenceDic[item])
                    yield return dicItem;
            }
            else
            {
                yield return item;
            }
        }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

次の行を実行して、アイテムにアクセスします。

Dictionary<string, List<string>> refData = new Dictionary<string, List<string>>();
LookupList lst = new LookupList(new List<string>() { "a.txt", "b.txt", "c.more" }, refData);
refData.Add("c.more", new List<string>() { "c.txt", "d.txt" });
List<string> flattenedItems = lst.ToList();
于 2013-03-10T04:12:08.663 に答える