1

I asked below question. I got an answer.

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

However, I have a problem in such scenario there are several min and max values in List. I want to use a LINQ expression in order to remove only one min and Max value in List.

Code snippet :

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();
        }
    }
}

output is ;

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

but, I want to get output like below ;

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

I'm thinking about several steps to solve this issue. Using LINQ: Is it Possible to use LINQ ?

1. Sorting
2. Remove First and Last index 

Code Snippet : Any Help ?

var newSortedValue = from pair in temp
                                 orderby pair.value descending
                                 where pair = temp.RemoveAt(0) && pair = temp.RemoveAt(temp.Count()-1)
                                 select pair;
2
  • Don't think there's anything you can do using only Linq. Commented Oct 30, 2014 at 11:06
  • 1
    In your ordered list, you want to skip the first element and then take everything except the last element, right? So orderedList.Skip(1).Take(orderedList.Count() - 2) should do the trick. Commented Oct 30, 2014 at 11:10

2 Answers 2

2

Sorting and removing first and last value should work just fine. You can do it like that:

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

//Edit: I was curious about Rashid Ali's solution (below) so I decided to perform a quick test. I created a list with 10 000 elements:

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

Then i removed single Min and Max element from the list using both methods and measured the time. My test code:

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);

Result: First method (order by): 11ms, Second method (remove): 3424ms I ran this test a couple of times and all results were similar. I didn't check what IL code earch method produces, but clearly using OrderBy outperforms combining Remove, Where and Min/Max

Sign up to request clarification or add additional context in comments.

Comments

0

Here is another way to get the result set you want without performing orderby operation:

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());

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.