如何使用LINQ:如果有几个最小值和最大值,只删除列表中的一个最小值和最大值

如何使用LINQ:如果有几个最小值和最大值,只删除列表中的一个最小值和最大值

问题描述:

我问下面的问题。我得到了答案。如何使用LINQ:如果有几个最小值和最大值,只删除列表中的一个最小值和最大值

How to use a LINQ in order to remove Min and Max value in List

不过,我有这样的情况的问题有几个分和列表最大值。 我想要使用LINQ表达式来删除列表中只有一个最小值和最大值。

代码片断:

namespace ConsoleApplication_lamdaTest 
{ 
    public struct TValue 
    { 
     public double x, y; 
     public double value { get { return Math.Sqrt(x * x + y * y); } } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      List<TValue> temp = new List<TValue> { 
       new TValue { x = 1, y =2 }, 
       new TValue { x = 3, y =4 }, 
       new TValue { x = 4, y =3 }, 
       new TValue { x = 3, y =1 }, 
       new TValue { x = 2, y =3 }, 
       new TValue { x = 1, y =4 }, 
       new TValue { x = 1, y =2 }, 
       new TValue { x = 1, y =2 } 
      }; 

      foreach(TValue item in temp) 
       Console.WriteLine(item.value.ToString()); 

      var newValue = from pair in temp 
          where pair.value < temp.Max(m => m.value) && pair.value > temp.Min(m => m.value) 
          select pair; 

      foreach (TValue item in newValue) 
       Console.WriteLine(item.value.ToString()); 

      Console.ReadKey(); 
     } 
    } 
} 

输出;

2.23606797749979 
5 
5 
3.16227766016838 
3.60555127546399 
4.12310562561766 
2.23606797749979 
2.23606797749979 
------------------- 
3.16227766016838 
3.60555127546399 
4.12310562561766 

但是,我想得到如下的输出;

2.23606797749979 
5 
5 
3.16227766016838 
3.60555127546399 
4.12310562561766 
2.23606797749979 
2.23606797749979 
------------------- 
5 
3.16227766016838 
3.60555127546399 
4.12310562561766 
2.23606797749979 
2.23606797749979 

我在想几个步骤来解决这个问题。使用LINQ:可以使用LINQ吗?

1. Sorting 
2. Remove First and Last index 

代码片段:任何帮助?

var newSortedValue = from pair in temp 
           orderby pair.value descending 
           where pair = temp.RemoveAt(0) && pair = temp.RemoveAt(temp.Count()-1) 
           select pair; 
+0

不要以为只有Linq才能做任何事情。 – DavidG 2014-10-30 11:06:59

+1

在您的有序列表中,您希望[跳过](http://msdn.microsoft.com/library/bb357513.aspx)第一个元素,然后[take](http://msdn.microsoft.com/library/ bb300906.aspx)除了最后一个元素之外的所有东西,对吧?所以'orderedList.Skip(1).Take(orderedList.Count() - 2)'应该做的。 – Corak 2014-10-30 11:10:04

排序和删除第一个和最后一个值应该工作得很好。你可以那样做:

var tempWithoutMinAndMax = temp.OrderBy(m => m.value).Skip(1).Take(temp.Count-2); 

//编辑:我很好奇,拉希德·阿里的解决方案(下),所以我决定进行一个快速测试。我创建的列表与10个000元素:

var list = new List<KeyValuePair<int, int>>(); 
for(int i=0;i<10000;i++) 
{ 
    list.Add(new KeyValuePair<int, int>(i,random.Next())); 
} 

然后,我使用这两种方法除去单个最小值和最大值元件从列表和测量的时间。我的测试代码:

Stopwatch watch = new Stopwatch(); 
watch.Start(); 
var ver1 = list.OrderBy(m => m.Value).Skip(1).Take(list.Count - 2).ToList(); 
watch.Stop(); 
var ver1time = watch.ElapsedMilliseconds; 
watch.Reset(); 
watch.Start(); 
list.Remove(list.Where(x => x.Value == list.Max(y => y.Value)).First()); 
list.Remove(list.Where(x => x.Value == list.Min(y => y.Value)).First()); 
watch.Stop(); 
var ver2time = watch.ElapsedMilliseconds; 
Console.WriteLine("First method (order by): {0}ms\nSecond method (remove): {1}ms", 
ver1time,ver2time); 

结果:第一种方法(按顺序):为11ms,第二种方法(删除):3424ms 我跑这个测试了几次,所有结果相似。我没有检查什么的IL代码目录操作搜索方法产生,但很明显,使用排序依据优于结合删除,在哪里以及最小/最大

这里得到的结果设定您想要而不执行排序依据操作的另一种方式:

temp.Remove(temp.Where(x => x.value == temp.Max(y => y.value)).First()); 
temp.Remove(temp.Where(x => x.value == temp.Min(y => y.value)).First());