LINQ表达式提取数字的具体数量和值

时间:2014-05-26 14:54:16

标签: c# linq

我知道我可以使用一些for循环来做这个,但是希望也许可以使用一些LINQ表达式完成,我只是模糊地熟悉LINQ,无论如何这里是我的场景,我有一个包含未知的整数列表如下所示的值,列表的大小将是已知的

var numList = new List<int>() { 12, 33, 24, 63, 45, 32, 3, 18, 22, 7, 10 };

我需要的是提取一个包含上述列表中数字的4个整数的新列表,但只有相互相加的数字大于100,所以一个例子就是...

var extractedList1 = new List<int>() { 12, 33, 24, 45 };
var extractedList2 = new List<int>() { 33, 24, 63, 32 };

显然这里有更多的组合,但我希望有一种有效的方法来实现这一点,任何帮助都会很棒。


UPDATE 谢谢大家,Selman22和Rob P.解决方案都很有效,并且在使用整数列表时完全符合我的要求,但是为了对事物进行另一次调整,我正在努力尝试使代码与List of一个名为Combo的自定义对象

public class Combo
{
    public Combo(int weight, int value)
    {
        Weight = weight;
        Value = value;
    }

    public int Weight { get; set; }
    public int Value { get; set; }
}

在这种情况下,我会有一个下面的组合对象列表

        var c1 = new Combo(3, 7);
        var c2 = new Combo(4, 6);
        var c3 = new Combo(2, 10);
        var c4 = new Combo(3, 13);
        var c5 = new Combo(3, 5);
        var c6 = new Combo(2, 7);

        var comboList = new List<Combo>() { c1, c2, c3, c4, c5, c6 };

每个组合对象的值将是其权重*值,因此c1将为21,c2将为24,依此类推。在这种情况下,我需要提取4个Combo对象的列表,其中每个对象的添加大于100,下面的示例

var extractedList1 = new List(){c1,c2,c3,c4};

调整现有代码可能只是一个简单的改变,但我现在对LINQ不是很熟悉,所以任何帮助都会很棒,感谢你们的帮助。

2 个答案:

答案 0 :(得分:3)

这可能不是一种有效的方法,但应该有效:

var numList = new List<int>() { 12, 33, 24, 63, 45, 32, 3, 18, 22, 7, 10 };

/* get all combinations including duplicates like: 
12,12,12,12 - 12,12,12,34 - 12,12,12,24  and so on
then put them into an array int[] */

var combinations = from x in numList
            from y in numList
            from z in numList
            from t in numList
            select new [] {x, y, z, t};

/* eliminate the duplicates (like 12-12-12-12) and 
   filter them based on Sum */
var result =  combinations
             .Where(x => x.Sum() > 100 && x.Distinct().Count() == x.Length);

// get distinct combinations using a custom equality comparer 
var distinctResults = result.Distinct(new Comparer()).ToList();

public class Comparer : IEqualityComparer<int[]>
{
    public bool Equals(int[] x, int[] y)
    {
        return x.OrderBy(a => a).SequenceEqual(y.OrderBy(a => a));
    }

    public int GetHashCode(int[] obj)
    {
        return obj.Select(x => x.GetHashCode()).Sum();
    }
}

from子句的这种使用称为Compound from clause,可让您轻松获得组合,您可以参考MSDN documentation以查看更多示例,而且来自Eric Lippert的this article可能很有帮助。

答案 1 :(得分:1)

这是我的看法:

var numList = new List<int> { 12, 33, 24, 63, 45, 32, 3, 18, 22, 7, 10 };

var answers = (from a in numList
               from b in numList where a >= b 
               from c in numList where b >= c 
               from d in numList where c >= d
               select new { Sum = a + b + c + d, Ans = "{" + a  + " " + b + " " + c + " " + d + "}"} into temp
               where temp.Sum > 100
               select temp.Ans).Distinct() ;

foreach (var answer in answers)
    Console.WriteLine(answer);

输出被截断(总共148个):

{33 32 24 12}
{33 32 24 18}
{33 32 24 22}
{33 32 22 18}
{63 33 12 3}
{63 33 12 7}
{63 33 12 10}
{63 33 24 12}
{63 33 24 3}
{63 33 24 18}
{63 33 24 22}
{63 33 24 7}
{63 33 24 10}
{63 33 32 12}
{63 33 32 24}
{63 33 32 3}
{63 33 32 18}
{63 33 32 22}
{63 33 32 7}
{63 33 32 10}
{63 33 18 12}
{63 33 18 3}
{63 33 18 7}
{63 33 18 10}
{63 33 22 12}
{63 33 22 3}
{63 33 22 18}
{63 33 22 7}
{63 33 22 10}
{63 33 7 3}
{63 33 10 3}
{63 33 10 7}
{63 24 12 3}
{63 24 12 7}
{63 24 12 10}
{63 24 18 12}
{63 24 18 3}