2012-03-19 4 views
1

У меня есть список, который содержит несколько строк, как показано ниже:Заменить часть элемента в виде списка строк

List<String> l = new List<String>(){ 
    "item1 1", 
    "item2 2", 
    "item3 3", 
    "item1 4", 
    "item1 5", 
    "item3 6"}; 

Я хотел бы подвести элементы, которые являются одинаковыми. Пример:

l = {"item1 10", "item2 2", "item3 9"} 

Я попытался это:

List<String> result = new List<String>(); 
for (int i = 0; i < total.Count; i++) 
{ 
    for (int j = 0; j < i; j++) 
    { 
     int diferenta = 0; 
     if (total[i].Substring(0, total[i].IndexOf(" ")).Equals(total[j].Substring(0, total[j].IndexOf(" ")))) 
    { 
     diferenta = int.Parse(ExtractNumber(total[i].Substring(total[i].IndexOf(" ")))) + int.Parse(ExtractNumber(total[j].Substring(total[j].IndexOf(" ")))); 
      total[i] = total[i].Replace(ExtractNumber(total[i].Substring(total[i].IndexOf(" "))), diferenta.ToString()); 
     result.Add(total[i]); 
    } 
} 

И, чтобы получить различные элементы:

List<String> final = result.Distinct().toList(); 

Мой путь не является правильным на всех, так что я хочу спросить вас Помогите.

ответ

3

Вы можете разделить каждый элемент, группы первым компонентом, а затем суммировать вторые компоненты вверх:

var groupQuery = l.Select(x => x.Split(new[] { ' ' })).GroupBy(x => x[0]); 
var sumQuery = groupQuery.Select(x => new { x.Key, Total = x.Select(elem => int.Parse(elem[1])).Sum() }); 
foreach (var total in sumQuery) 
{ 
    Console.WriteLine("{0}: {1}", total.Key, total.Total); 
} 

Этот код явно пропускает кучу ошибок проверки (что произойдет, если строка не расщепляется , или не имеет второго компонента, который может быть проанализирован?), но это может быть добавлено без особых трудностей.

1

Без обработки плохих данных (например, не разделенных пробелом и т. Д.).

int sumTotal = (from i in l 
     let parts = i.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) 
     let id = parts[0] 
     let count = int.Parse(parts[1]) 
     group count by id into Numbers 
     where Numbers.Count() != 1 
     select Numbers.Sum()).Sum(); 

Редактировать: Не видел, что вы хотите, чтобы считать каждый элемент, даже если он не имеет дубликат. Это даже проще, вам просто нужно удалить where CountGroup.Count() != 1 из запроса :)

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

int number=0; 
int sum = (from i in l 
      let parts = i.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) 
      where parts.Length==2 
      let id = parts[0] 
      let isInt = int.TryParse(parts[1], out number) 
      where isInt 
      group number by id into Numbers 
      select Numbers.Sum()).Sum(); 
1
List<string> outputList = 
    inputList.GroupBy(s => s.Split(' ')[0]) 
      .Select(g.Key + " " + g.Sum(s => int.Parse(s.Split(' ')[1])).ToString()); 

Hooray для LINQ! :)

Примечание: Улавливание ошибок отсутствует, и я предполагаю, что данные всегда правильные. Я не тестировал код для производительности или ошибок.

0

Итерации по списку. Для каждого элемента разделите на " ". Добавьте префикс (splits [0]) к карте (String: Integer). Если строка существует на карте, сначала извлекайте ее значение, затем добавьте текущее значение элемента (split [1]), затем добавьте сумму обратно к карте.

В конце ваша карта будет иметь сумму для каждой строки. Просто перебирайте элементы карты для вывода.