用于将多个字符串部分列表与主字符串列表进行比较的模式

本文关键字:列表 字符串 比较 模式 字符串部 用于 | 更新日期: 2023-09-27 18:37:28

所以我有一个'uber'列表:DestinationColumn,有100个字符串。为了简单起见,总是 100。

它来自几个源列,ColA,ColB。 其中一些将有 100 个字符串,有些将更少。

所以,例子:

ColA 具有字符串 1-33、40-70 和 90-100 的值。 它获得第一优先级,并将这些字符串的所有值填充到目标列中。ColB 的值为 1-40 和 70-100。 在存在空白的地方,它会填补它,但它不能压倒 ColA 字符串。

现在我想确保这种情况已经发生。

列出源可

乐,列出源可列B和列表目标列。

首先,我编写了一个函数来比较两个列表,以查看它们是否包含相同的字符串:

public static bool ListEquals<T>(IList<T> list1, IList<T> list2)
    {
        if ((list1 == null) || (list2 == null))
        {
            return false;
        }
        if (list1.Count != list2.Count)
            return false;
        for (int i = list1.Count - 1; i >= 0; --i)
        {
            if (!list1[i].Equals(list2[i]))
            {
                return false;
            }
        }
        return true;
    }

现在我想保持它的通用性,但采用 x 个源列,并确保所有内容现在都正确位于一个目标列中。这样做有没有一般模式?

我目前的想法是一个循环,将 ColA 的所有条目与目的地 Col 标记出来,重复 B,依此类推,然后确保所有条目没有被击中两次,并且所有条目都被击中一次。

用于将多个字符串部分列表与主字符串列表进行比较的模式

要按照您的描述合并两列,您可以简单地这样做

ColA.Zip(ColB, (a, b) => a??b)

所以:

void Main()
{
    IEnumerable<IEnumerable<string>> cols=
        new string[][]
        {
            new string[]{"monkey", "frog", null, null, null, null},
            new string[]{null, null, null, null, "cat", "giraffe"},
            new string[]{null, null, null, "dog", "fish", null}
        };
    cols.MergeLeft().Dump();
    //gives: "monkey", "frog", null, "dog", "cat", "giraffe" 

}
static class Ex
{
    public static IEnumerable<T> MergeLeft<T>
        (this IEnumerable<IEnumerable<T>> cols) where T:class
    {
        var maxItems = cols.Max(x => x.Count());
        var leftMerged = 
            cols
                .Aggregate(
                    Enumerable.Repeat((T)null, maxItems),
                    (acc,col) => acc.Zip(col, (a, b) => a ?? b));
        return leftMerged;
    }
}

编辑

这是一个更高效的MergeLeft版本,不需要maxItems消除下面描述的费用@Enigmativity:

static class Ex
{
    public static IEnumerable<T> MergeLeft<T>
        (this IEnumerable<IEnumerable<T>> cols) where T:class
    {
        return cols
            .Aggregate(
                Enumerable.Empty<T>(),
                (acc,col) => 
                acc
                    .Concat(Infinite<T>(null))
                    .Zip(col, (a, b) => a ?? b));   
    }
    private static IEnumerable<T> Infinite<T>(T item)
    {
        for(;;){yield return item;}
    }
}

我不完全确定我是否理解您要做什么,因为我不了解您的ListEquals的目的。无论如何,我会这样走:

    public static void FillDest<T>(IList<T> dest, IList<IList<T>> srcLists)
        where T : class
    {
        bool goon = true;
        int idx = 0;
        dest.Clear();
        while (goon)
        {
            goon = false;
            bool added = true;
            foreach (IList<T> aSrc in srcLists)
            {
                added = false;
                T anItem;
                if (aSrc.Count <= idx)
                {
                    added = true;
                    continue;
                }
                goon = true;
                if ((anItem = aSrc[idx]) != null)
                {
                    dest.Add(anItem);
                    added = true;
                    break;
                }
            }
            if (!added)
                dest.Add((T)null);
            idx++;
        }
    }