用于将多个字符串部分列表与主字符串列表进行比较的模式
本文关键字:列表 字符串 比较 模式 字符串部 用于 | 更新日期: 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++;
}
}