所以我有一个'超级'列表:DestinationColumn,有100个字符串。简而言之,总是100,
它来自几个源列,ColA,ColB。其中一些将有100个字符串,有些会少一些。
所以,例如:
ColA具有字符串1-33,40-70和90-100的值。它具有第一优先级,并将所有值填入DestinationColumn中以获取这些字符串。 ColB的值为1-40和70-100。如果存在间隙,则填充它,但它不能覆盖ColA字符串。
现在我想确保发生这种情况。
列出sourceColA,列出sourceColB 和ListdestinationColumn。
首先,我编写了一个函数来比较两个列表,看它们是否包含相同的字符串:
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的条目标记为destinationCol,重复B,依此类推,然后确保所有条目都不会被击中两次并且所有条目都被击中一次。
答案 0 :(得分:1)
要按照您的描述合并两列,您可以像
一样进行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;}
}
}
答案 1 :(得分:0)
我不完全确定我明白你要做什么,因为我不明白你的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++;
}
}