2010-11-02 91 views
0

问题的快速说明:我有一个特定顺序的项目列表,我将它们分成2个列表,左和右。现在,假设我想要打印10个元素,并且需要注意的是,我想从右侧列表中尽可能多地打印(即,如果此列表包含10个元素,那么这个列表中的所有元素都很棒),但是如果我缺乏,我想从左边的列表打印,但是那些最接近右边列表的项目。将一个序列分组为两组,然后使用LINQ基于第二组中的元素的数量从第一组打印第一组使用LINQ

我有一个想法是这个......不知道我们是否可以写出更短,更清晰的代码。

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;  

这的确是所有我的大脑能想出,如果你知道这样做,请让我知道一个更简单的方法。我还是要aactually写这个真正的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]); 
} 

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

+0

什么是你的商业规则''但那些项目是最接近右列表.'?在奇数进入A甚至进入B的例子中,什么是“最接近的”? – JumpingJezza 2010-11-02 06:09:12

+0

从左到右,即如果我有,左侧列表中的1,2,3位,以及右侧列表中的4,5,6 ...我需要打印5个项目......他们将是2,3, 4,5,6 ...有帮助吗? – user494352 2010-11-02 06:23:58

+0

是的 - 高科技公司的解决方案,虽然我不得不摆弄语法来让它工作:) – JumpingJezza 2010-11-02 06:45:53

回答

0

我对你想要做的事情不知所措......但是,我会用你的几率甚至是榜样来刺杀它。我将把我的例子写成一个标准的C#控制台应用程序。

我不知道如何使用LINQ来分割一个枚举。因此,我的示例将使用两个单独的lambda表达式将IEnumerable分为不同的组。然后,我将指定数量的项目从A分配给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,但我已经离开了这个部分,以避免更多的混乱。

1

很难跟踪你的问题。你也许应该从listA和listB开始,并解释你真正想从他们那里得到什么。我想你是要求:

var result = (listA.Reverse().Take(Y).Concat(listB.Reverse())).Take(Z).Reverse(); 
相关问题