CRK
CRK

Reputation: 337

Linq remove only one item if there are duplicate

I have 5 numbers i.e.: 1 1 1 2 3; I have to sum them except the minimum number, but I can remove it only one time (if the minimum occurs more than one time I have to maintain the rest). How can I do it with Linq? I thought:

var min = nums.Min();
var minSum = nums.Where(x => x != min).Sum();

But it remove all the 1s from the lists. I need a way to go out from the where if there's more than 1 occurence.

All this with Linq if it's possible.

Upvotes: 8

Views: 1014

Answers (4)

Magnus
Magnus

Reputation: 46919

A simple solution would be the following, but would iterate the collection twice.

var nums = new int[]{ 1, 1, 1, 2, 3 };
var minSum = nums.Sum() - nums.Min();

For a solution that only iterates the collection once using Linq you could write:

var nums = new int[] { 1, 1, 1, 2, 3 };
var minSum = 
    nums.Aggregate(
        new {
            Min = int.MaxValue,
            Sum = 0
        },
        (accumulator, i) => new {
            Min = Math.Min(i, accumulator.Min),
            Sum = accumulator.Sum + i
        }, (accumulator) => accumulator.Sum - accumulator.Min);

Upvotes: 11

René Vogt
René Vogt

Reputation: 43876

Though Magnus already seems very well, it still needs to iterate the list twice. Once to find the minium and once to find the sum.

So I just show a more verbose but therefor faster implementation:

var nums = new int[]{ 1, 1, 1, 2, 3 };
int sum = 0;
int min = int.MaxValue;
foreach (int i in nums)
{
    sum += i;
    if (i < min) min = i;
}
if (nums.Length > 0) sum -= min;

I'm not sure if a for loop maybe faster than foreach, but I think that difference should not really be measurable.


For pwas comment I add the for version again:

for(int i=0; i<nums.Length; i++)
{
    int j = nums[i];
    sum += j;
    if (j < min) min = j;
}
if (nums.Length > 0) sum -= min;

Upvotes: 5

fubo
fubo

Reputation: 45947

Here is a one liner which even works if your array is empty

int[] nums = { 1, 1, 1, 2, 3 };
int minSum = nums.OrderBy(x =>x).Skip(1).Sum();

Upvotes: 13

Ivan Kishchenko
Ivan Kishchenko

Reputation: 815

Try this:

var nums = new int[] { 1, 1, 1, 2, 3 };

var list = nums.ToList();
list.Remove(nums.Min());
var minSum = list.Sum();

Upvotes: 1

Related Questions