C# LINQ Arrange Multiple Columns Value and Resign to Specifi c Columns - PullRequest
1 голос
/ 27 мая 2020

Я пробовал это с Foreach l oop, с новым массивом, и сейчас он работает, но я хочу изучить и посмотреть, есть ли лучший способ сделать это с помощью LINQ lambda. таблица вроде этой

public class fruits
{
   string id {get;set;}
   string fruit1 {get;set;}
   string fruit2 {get;set;}
   string fruit3 {get;set;}
}

Почему-то не все поля фруктов в таблице были заполнены, например:

id    fruit1    fruit2    fruit3
1     Apple               Kiwi
2               Lime
3                         Watermelon
4               Oranges   Grapes

Требуется вывод, например:

id    fruit1    fruit2    fruit3
1     Apple     Kiwi          
2     Lime          
3     Watermelon                    
4     Oranges   Grapes           

попробовал следующее шаг, чтобы заставить это работать

  1. foreach l oop через объект списка фруктов
  2. добавить fruit1, fruit2, fruit3 в новый массив
  3. создать для l oop на основе массива. длина присваивает значение, например, object fruit [i]

Я хотел бы знать, есть ли лучший способ сделать это с помощью LINQ lambda.

спасибо

Ответы [ 4 ]

2 голосов
/ 27 мая 2020

Другой подход с Linq

fruits[] output = input.Select(x => {
var items = new[] { x.fruit1, x.fruit2, x.fruit3 }.Where(y => !string.IsNullOrEmpty(y));
                return  new fruits() {
                    id = x.id,
                    fruit1 = items.ElementAtOrDefault(0),
                    fruit2 = items.ElementAtOrDefault(1),
                    fruit3 = items.ElementAtOrDefault(2)
                };}).ToArray();

https://dotnetfiddle.net/OXYWpW


imo лучший подход с l oop

foreach (fruits item in fruitarray)
{
    var columns = new[] { item.fruit1, item.fruit2, item.fruit3 }.Where(y => !string.IsNullOrEmpty(y));
    item.fruit1 = columns.ElementAtOrDefault(0);
    item.fruit2 = columns.ElementAtOrDefault(1);
    item.fruit3 = columns.ElementAtOrDefault(2);
}

https://dotnetfiddle.net/RVhl9n

2 голосов
/ 27 мая 2020

Таким образом, при использовании тернарных условных операторов это будет выглядеть так, хотя использование al oop будет более читаемым.

list = list.Select(x => new fruits
        {
            id = x.id,
            fruit1 = x.fruit1 ?? x.fruit2 ?? x.fruit3,
            fruit2 = !string.IsNullOrEmpty(x.fruit1) ? (x.fruit2 ?? x.fruit3) : string.IsNullOrEmpty(x.fruit2) ? null : x.fruit3,
            fruit3 = string.IsNullOrEmpty(x.fruit1) || string.IsNullOrEmpty(x.fruit2) ? null : x.fruit3
        }).ToList();
1 голос
/ 27 мая 2020

сначала я хотел бы go составить список этих фруктов, чтобы вы действительно могли что-то с ними сделать. желательно, чтобы вы для начала сохраняли их в списке;

добавляем свойство плодов, которое возвращает фрукты в виде списка.

public List<string> fruit
    {
        get { return new List<string> { this.fruit1, this.fruit2, this.fruit3 };}
        set {
            this.fruit1 = value.ElementAtOrDefault(0);
            this.fruit2 = value.ElementAtOrDefault(1);
            this.fruit3 = value.ElementAtOrDefault(2);
        }
    }

, таким образом беря список объекта Fruits:

List<Fruits> fruitList = {...};

Затем вы можете удалить все фрукты там, где ничего нет, создавая таким образом список без пустых мест.

fruitList.ForEach(s => s.fruits =  s.fruits.Where(x => !string.IsNullOrEmpty(x)).ToList());

Однако этот список может быть короче предыдущего списка, так как все пустые струны удаляются. Поэтому мы должны проверить, существует ли еще значение в соответствующем индексе. Мы делаем это с помощью ElementAtOrDefault , это возвращает null, если в индексе нет значения.

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

1 голос
/ 27 мая 2020

Linq-операции Выбрать , Пропустить и FirstOrDefault :

var projection = fruitses.Select(r=> 
    new fruits { 
        id = r.id, 
        fruit1 = new List<string>(){r.fruit1, r.fruit2, r.fruit3}   
            .FirstOrDefault(s=>!string.IsNullOrEmpty(s)), 
        fruit2 = new List<string>(){r.fruit2, r.fruit3}
            .Skip(r.fruit1==null?1:0)
            .Skip(r.fruit2==null?1:0)
            .FirstOrDefault(s=> !string.IsNullOrEmpty(s)), 
        fruit3 = new List<string>(){r.fruit3}
            .Skip(r.fruit1==null?1:0)
            .Skip(r.fruit2==null?1:0)
            .FirstOrDefault(s=> !string.IsNullOrEmpty(s))
    });

. NET Скрипка здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...