Нужна помощь с использованием Linq для преобразования списка в другой список - PullRequest
2 голосов
/ 09 мая 2020

Допустим, у меня есть список, содержащий 1 запись:

[
  {
    "AccountNumber": 1234,
    "eDocConfirms": true,
    "eDocStatements": true,
    "eDocTaxforms": false
  }
]

Этот список представляет собой строго типизированный объект со следующими свойствами:

        public int AccountNumber { get; set; }
        public bool? eDocConfirms { get; set; }
        public bool? eDocStatements { get; set; }
        public bool? eDocTaxforms { get; set; }

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

[
  {
    "AccountNumber": 1234,
    "EDocumentTypeName ": "Confirms"
  },
  {
    "AccountNumber": 1234,
    "EDocumentTypeName": "Statements"
  }
]

Этот новый список будет списком другого типа:

public class DeliveryPreference
    {
        public int AccountNumber { get; set; }
        public string EDocumentTypeName { get; set; }
    }

Обратите внимание, что налоговые формы не были включены в новый список потому что в первом списке было установлено значение false.

Я знаю, что могу легко сделать это с помощью некоторых циклов, но я бы предпочел использовать LINQ.

Я понимаю, что Stack Overflow предпочитает, чтобы я показывал то, что я пробовал, но у меня возникают проблемы с осознанием этого.

Ответы [ 2 ]

4 голосов
/ 09 мая 2020

В этом случае я бы использовал дополнительную функцию

public static IEnumerable<string> GetTrueProperties(Data t)
{
    if (t.eDocConfirms == true) yield return "Confirms";
    if (t.eDocStatements == true) yield return "Statements";
    if (t.eDocTaxForms == true) yield return "Tax";
}

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

, тогда это будет выглядеть как

var list = new List<Data> {
new Data
{
    AccountNumber = 1,
    eDocConfirms = true,
    eDocStatements = true,
    eDocTaxForms = false
}
};
list.SelectMany(item => GetTrueProperties(item).Select(p => new DeliveryPreference
{
    AccountNumber = item.AccountNumber,
    EDocumentTypeName = p
}));
0 голосов
/ 09 мая 2020

Это очень уродливый код, но он работает. Это должно быть легко понять. Отражение можно извлечь в новую функцию.

using System;
using System.Linq;

public class Program
{
    public class Account {
      public int AccountNumber { get; set; }
        public bool? eDocConfirms { get; set; }
        public bool? eDocStatements { get; set; }
        public bool? eDocTaxforms { get; set; }
    }

    public class DeliveryPreference
    {
        public int AccountNumber { get; set; }
        public string EDocumentTypeName { get; set; }
    }

    public static void Main()
    {
        var acc = new Account {
            AccountNumber = 10,
            eDocConfirms = true,
            eDocStatements = false,
            eDocTaxforms = true
        };

        var transformed = acc.GetType()
            .GetProperties()
            .Where(p => p.PropertyType == typeof(bool?) 
                   && ((bool?)p.GetValue(acc)).HasValue
                  && ((bool?)p.GetValue(acc)).Value)
            .Select(p => new DeliveryPreference {
                AccountNumber = acc.AccountNumber,
                EDocumentTypeName = p.Name.Substring(4)
            });

        foreach (var t in transformed) {
            Console.WriteLine(t.AccountNumber);
            Console.WriteLine(t.EDocumentTypeName);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...