我想将2个列表合并到一个列表中,但是,它必须按特殊顺序排列。
例如,我有一个类型A的列表:
{A,A,A,A,A,A ....}
还有一个B类清单:
{B,B,B,B ....}
期望的结果应该是这样的:
{A,A,B,A,A,B,A,A,B}
合并应该从列表A中获取2个项目,然后从列表B中获取1个项目。
有一点需要注意的是,如果一个列表变为空,请使用第二个列表的项填充所有其余项。
我试图用LINQ找到一种优雅的方式。
继承我的代码,但它有点长,我希望通过linq有更好的方法:
非常感谢。
public IList<PersonBase> Order(IList<Person1> people1, IList<Person2> people2)
{
if (people1.IsNullOrEmpty())
return people2;
if (people2.IsNullOrEmpty())
return people1;
List<PersonBase> orderedList = new List<PersonBase>();
var people1Count = 0;
var people2Count = 0;
while (people2Count < people2.Count || people1Count < people1.Count)
{
var people1ToAdd = tags.Skip(people1Count).Take(1).ToList();
people1Count = people1.Count();
orderedList.AddRange(people1ToAdd);
if (people1Count >= people1.Count)
{
orderedList.AddRange(people2.Skip(people2Count));
break;
}
var people2ToAdd = people2.Skip(peopleCount).Take(2).ToList();
people2Count = people2.Count();
orderedList.AddRange(people2ToAdd);
if (people2Count >= people2.Count)
{
orderedList.AddRange(people1.Skip(people1Count));
break;
}
}
return orderedList;
}
答案 0 :(得分:1)
这是非常可怕的代码,但也做你想要的。基本上我们会跟踪每个列表索引并有一个int
来跟踪用于填充结果数组的列表。
List<int> list1 = new List<int>() { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
List<int> list2 = new List<int>() { 2, 2, 2, 2, 2 };
int list1Counter = 0;
int list2Counter = 0;
int arraychecker = 1;
int[] resultArray = new int[list1.Count + list2.Count];
for (int i = 0; i < resultArray.Length; i++)
{
if (list1Counter < list1.Count && list2Counter < list2.Count)
{
if (arraychecker == 1 || arraychecker == 2)
{
resultArray[i] = list1[list1Counter];
list1Counter++;
arraychecker++;
}
else
{
resultArray[i] = list2[list2Counter];
list2Counter++;
arraychecker = 1;
}
}
else if (list1Counter < list1.Count)
{
resultArray[i] = list1[list1Counter];
list1Counter++;
}
else
{
resultArray[i] = list2[list2Counter];
list2Counter++;
}
}
答案 1 :(得分:0)
您可以计算每个项目的索引,然后按该索引排序。
var mergedList =
listA.Select((item, index) =>
new { Index = index / 2 * 3 + (i % 2), Item = item})
.Concat(listB.Select((item, index) =>
new { Index = i * 3 + 2, Item = item}))
.OrderBy(x => x.Index)
.Select(x => x.Item)
.ToList();
或者写一个方法。这样更有效,因为它不需要排序;它只会遍历每个列表一次。
static IEnumerable<T> Alternate<T>(IEnumerable<T> sourceA, IEnumerable<T> sourceB) {
using (IEnumerator<T> eA = sourceA.GetEnumerator(), eB = sourceB.GetEnumerator()) {
bool aHasItems = true, bHasItems = true;
while (aHasItems || bHasItems) {
if (eA.MoveNext()) yield return eA.Current;
if (aHasItems = eA.MoveNext()) yield return eA.Current;
if (bHasItems = eB.MoveNext()) yield return eB.Current;
}
}
}
答案 2 :(得分:0)
这是我能做的最好的事情:
string[] test1 = { "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A" };
string[] test2 = { "B", "B" };
string[] result = test2.SelectMany((value, key) => test1.Skip(key * 2).Take(2).Concat(test2.Skip(key).Take(1))).ToArray();
result = result.Concat(test1.Skip(result.Length / 3 * 2).Take(test1.Length - result.Length / 3 * 1)).ToArray();
这将从array1中获取2,然后从数组2中获取1,然后添加较长的一个的剩余部分。输出:
AABAABAAAAAAAAA