2017-02-16 12 views
8

У меня 5 номеров i.e .: 1 1 1 2 3; Я должен их суммировать, за исключением минимального числа, но я могу удалить его только один раз (если минимум возникает более одного раза, я должен поддерживать остальные). Как я могу это сделать с Linq? Я думал:Linq удалить только один товар, если есть дубликат

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

Но он удаляет все 1 из списков. Мне нужен способ выйти из того места, где есть более одного события.

Все это с Linq, если возможно.

+0

Существуют ли какие-либо другие критерии? Как вы ищете очень быструю реализацию или лучший читаемый или самый маленький код? Просто прошу не отвечать в неправильном направлении. –

+0

За любопытством я могу увидеть самую быструю реализацию? – CRK

+0

Самая быстрая реализация - использовать случайный цикл 'for' (но для такой небольшой группы элементов это не будет существенным улучшением). – pwas

ответ

11

Простое решение будет следующее, но будет перебирать коллекцию дважды.

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

Для решения, которое только итерации коллекции раза с помощью Linq вы могли бы написать:

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

Вот один вкладыш, который работает даже если массив пуст

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

Да, я тоже хотел опубликовать это, но боялся немедленных комментариев «Это слишком медленно». –

1

Попробуйте это:

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

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

Хотя Magnus уже, кажется, очень хорошо, он по-прежнему необходимо повторите этот список дважды. Однажды, чтобы найти миниум и один раз, чтобы найти сумму.

Так что я просто показать более многословный, но дл него быструю реализацию:

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; 

Я не уверен, если for цикла может быть быстрее, чем foreach, но я думаю, что разница не должна действительно быть измеримой.


Для людей со СПИДом комментарий Я снова добавить версию for:

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; 
+0

'for' примерно в два раза быстрее: http://codebetter.com/patricksmacchia/2008/11/19/an-easy-and-efficient-way-to-improve-net-code-performances/ – pwas

+0

Это также стоит помнить, чтобы сделать 'sum' типа' long' - если мы не знаем, что большие данные: :) – pwas

+1

@pwas thx для ссылки, я сделаю некоторые тесты для себя. Но на первый взгляд кажется, что это справедливо только для 'List ', а не для' int [] '. И я предполагаю, что это связано с предсказанием отрасли или чем-то подобным. –

 Смежные вопросы

  • Нет связанных вопросов^_^