将序列分组为两组,然后使用LINQ基于第二组中的元素数从第一组打印

时间:2010-11-02 05:44:18

标签: c# linq

问题的快速解释:我有一个特定顺序的项目列表,我将其分为两个列表,左侧和右侧。现在,假设我要打印10个元素,需要注意的是我想从正确的列表中尽可能多地打印(例如,如果此列表包含10个元素,那么这些元素中的所有元素都很好),但是如果我做不到,我想从左侧列表打印,但是那些最接近右侧列表的项目。

我有一个想法就是这个...不知道我们是否可以编写更短,更简洁的代码。

var totalToPrint = 10
var listA,listB = originalList group by where some condition that is bool and hence two lists
var interimRightList = listB.Take(totalToPrint);
var myfinallist = listA.Skip(listA.length - interimRightList.Count()) + interimRightList;    

这真的是我脑子里想出来的,如果你知道一个更简单的方法,请告诉我。我仍然需要为此实际编写真正的C#代码......我让这听起来很简单(也许是这样),但不知道......

这是正式的描述:

给定一个枚举,例如:{1,2,3,4,5,6,7,8,9,10,11,12}

我想将它们分为两组,A和B ......将提供一个函数来决定它们属于哪一组。为简单起见,假设它按照上述顺序放入奇数集和偶数集。

现在,我想从集合B输出尽可能多的项目(假设X项目数量),然后从集合A输出尽可能多的项目(假设Y项目数量),这样X + Y = Z和不再。换句话说,如果Z是10,X是10,那么我们从列表A中选择任何东西。类似地,如果Z是5,X是10,那么我们从B中选择5个元素,而从A中选择没有。

此外,这应该是稳定的,即不应改变排序。

更完整的例子

{1,2,3,4,5,6,7,8,9,10,11,12} - 让我们假设我们的设定分割函数是任何小于11的元素,进入A,否则去到B.我们说我们必须打印3个元素。因此,我们将从B中选择{11,12},然后从A中选择{10}并按顺序打印...这样将打印10,11,12。

以下是普通代码中的外观:

int remaining = 10;
int a = 0;
for (int i = 0; i < listB.Count() && remaining > -1; ++i, ++a, remaining--)
{
   // don't print(listB[i]); i.e do nothing
}

if (remaining > 0)
{
    for (int i = listA.length - remaining; i < listA.length; ++i)
    {
        print(listA[i]);
    }
}

for (int i = 0; i < a; ++i)
{
     print(listB[i]);
}

仅供参考,这听起来似乎不是面试问题,但这是一个现实世界的问题。

2 个答案:

答案 0 :(得分:1)

很难关注你的问题。您应该从listA和listB开始,并解释您真正希望从中获得的内容。我想你要求:

var result = (listA.Reverse().Take(Y).Concat(listB.Reverse())).Take(Z).Reverse();

答案 1 :(得分:0)

我对你要做的事情感到茫然......尽管如此,我会用你的赔率甚至例子来刺激它。我将把我的例子写成标准的C#控制台应用程序。

我无从使用LINQ分割可枚举的方法。因此,我的示例将使用两个单独的lambda表达式将IEnumerable拆分为不同的组。然后我从指定给AB的指定数量的项目。在此之后,我将B中指定数字的余数(如果有的话)合并到AB中。最后一节迭代并将每个打印成CSV字符串。

    static void Main(string[] args)
    {
        int[] numArray = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        OddsAndEvens(7, numArray);
        OddsAndEvens(4, numArray);
    }

    public static void OddsAndEvens(int numToPrint, int[] array)
    {
        var a = array.Where(n => n % 2 == 0); // evens
        var b = array.Where(n => !(n % 2 == 0)); // not evens, thus odds
        var ab = a.Take(numToPrint);
        ab = ab.Union(b.Take(numToPrint - ab.Count()));

        foreach (int i in ab)
        {
            Console.Write(i + ", ");
        }
        Console.WriteLine();
        Console.WriteLine("Press any enter to continue...");
        Console.ReadKey();
    }

注意:一个更好的方法可能是将数组转换为字符串,然后使用string.Join创建一个CSV,但我已经把这部分留下来以避免更多的混淆。