如何以這樣的方式2分集組合,所得集合包含的值替代地從兩個集合合併2個集合
實施例: - 柱A = [1,2,3,4] 色柱B = [5,6,7,8]
結果山口C = [1,5,2,6,3,7,4,8]
如何以這樣的方式2分集組合,所得集合包含的值替代地從兩個集合合併2個集合
實施例: - 柱A = [1,2,3,4] 色柱B = [5,6,7,8]
結果山口C = [1,5,2,6,3,7,4,8]
有很多方法可以做到這一點,具體取決於輸入類型和所需輸出類型。然而,我沒有意識到圖書館的方法。你必須「滾動你自己的」。
一種可能性將是一個LINQ風格的迭代方法,假設我們只知道輸入的集合是他們實現IEnumerable<T>
:
static IEnumerable<T> Interleave(this IEnumerable<T> a, IEnumerable<T> b)
{
bool bEmpty = false;
using (var enumeratorB b.GetEnumerator())
{
foreach (var elementA in a)
{
yield return elementA;
if (!bEmpty && bEnumerator.MoveNext())
yield return bEnumerator.Current;
else
bEmpty = true;
}
if (!bEmpty)
while (bEnumerator.MoveNext())
yield return bEnumerator.Current;
}
}
謝謝。只是爲了好奇我們可以在LINUX中實現ZIP運算符嗎?這是.NET 4.0的新手段來解決問題嗎? – praveen 2012-03-22 03:21:46
@praveen Anthony Pegram的回答使用zip,但他似乎刪除了它。這不是最有效的執行,但它確實使代碼更簡單。問題在於它會截斷更長的序列,因此如果分別使用4項和5項輸入集合,則輸出將有8個項目,並且會丟失第二個集合中的最後一項。這可能是爲什麼安東尼刪除了他的答案。 – phoog 2012-03-22 03:28:32
謝謝@phoog的澄清 – praveen 2012-03-22 03:34:53
int[] a = { 1, 2, 3, 4 };
int[] b = { 5, 6, 7, 8 };
int[] result = a.SelectMany((n, index) => new[] { n, b[index] }).ToArray();
如果集合A和b都沒有同樣的長度,你需要小心使用b[index]
,也許你需要:index >= b.Length ? 0 : b[index]
謝謝它解決了我的問題。 – praveen 2012-03-22 03:19:42
使用LINQ的聯盟擴展名,例如:
var colA = new List<int> { 1, 2, 3, 4 };
var colB = new List<int> { 1, 5, 2, 6, 3, 7, 4, 8};
var result = colA.Union(colB); // 1, 2, 3, 4, 5, 6, 7, 8
「包含值交替地」,因此A的索引0仍然存在,B的索引0在新數組中爲1等。 – Lander 2012-03-22 02:58:43
假設兩個集合長度相等的:
Debug.Assert(a.Count == b.Count);
for (int i = 0; i < a.Count; i++)
{
c.Add(a[i]);
c.Add(b[i]);
}
Debug.Assert(c.Count == (a.Count + b.Count));
如果集合不一定具有相同的長度,可以考慮擴展方法:
public static IEnumerable<T> AlternateMerge<T>(this IEnumerable<T> source,
IEnumerable<T> other)
{
using(var sourceEnumerator = source.GetEnumerator())
using(var otherEnumerator = other.GetEnumerator())
{
bool haveItemsSource = true;
bool haveItemsOther = true;
while (haveItemsSource || haveItemsOther)
{
haveItemsSource = sourceEnumerator.MoveNext();
haveItemsOther = otherEnumerator.MoveNext();
if (haveItemsSource)
yield return sourceEnumerator.Current;
if (haveItemsOther)
yield return otherEnumerator.Current;
}
}
}
並使用:
List<int> A = new List<int> { 1, 2, 3 };
List<int> B = new List<int> { 5, 6, 7, 8 };
var mergedList = A.AlternateMerge(B).ToList();
如果在收到錯誤的返回值後調用MoveNext,許多枚舉器將引發異常。這個答案不能防止這種情況發生。 – phoog 2012-03-22 03:11:14
這不是文檔所說的,我沒有看到至少對於常規集合(工作得很好) - 爲這種行爲舉個例子? (docs say **當枚舉器在這個位置時,對MoveNext的後續調用也會返回false,直到調用Reset爲止。**) – BrokenGlass 2012-03-22 03:14:19
不,現在我發佈了這個,我找不到任何支持證據。我確信我以前見過它。也許這是由沒有閱讀過文檔的人編寫的專有代碼。 – phoog 2012-03-22 03:18:34
請問收藏始終是相同的長度? – Lander 2012-03-22 02:54:00
集合A和B的類型是什麼?結果集合C具有什麼類型? – phoog 2012-03-22 02:55:28
收集的數據類型可以是任何東西,長度可能不同 – praveen 2012-03-22 03:07:00