Reputation: 337
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
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
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
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
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