简体   繁体   English

从列表中过滤<T>名单<T>

[英]Filter from List<T> of List<T>

My Concern is based on the same question I had asked earlier and got the resolution.我的担忧基于我之前提出并得到解决的相同问题

I initially thought I am getting the correct response, but to see I am not.我最初以为我得到了正确的回应,但事实证明我没有。 My Data is like this:我的数据是这样的:

在此处输入图片说明

and If I filtered like this如果我像这样过滤

var result = overdues.Where(a=>a.Accounts.Any(b=>b.AccountId.Equals("JKB2")));

I am getting the result like this:我得到这样的结果:

在此处输入图片说明

But I want the result only to have Accounts equalling to JKB2 not Accounts that have JKB2.但我希望结果只具有等于 JKB2 的帐户而不是具有 JKB2 的帐户。 Hence what I have highlighted down here should be in the result and not others:因此,我在这里强调的应该是结果而不是其他:

在此处输入图片说明

Technically, the result should be like this ( I just wrote a pseudocode in the form of JSON):从技术上讲,结果应该是这样的(我只是写了一个JSON形式的伪代码):

    [
    {
    Slab: T3,
    Value: 500,
    Percentage: 0
    Accounts: {
    AccountId:JKB2,
    AccountName:JKB2,
    SalesCode:JKB,
    Value:500
    }
    },
{
    Slab: T5,
    Value: 500,
    Percentage: 0
    Accounts: {
    AccountId:JKB2,
    AccountName:JKB2,
    SalesCode:JKB,
    Value:500
    }
    }
    ]

My LinqPad working is here:我的 LinqPad 工作在这里:

public class OverdueModel
    {
        public string Slab { get; set; }
        public double Value { get; set; }
        public double Percentage { get; set; }
        public List<OverdueSlabAccounts> Accounts { get; set; }
    }

    public class OverdueSlabAccounts
    {
        public string AccountId { get; set; }
        public string AccountName { get; set; }
        public string SalesCode { get; set; }
        public string Value { get; set; }
    }


void Main(){
    List<OverdueModel> overdues = new List<OverdueModel>();
    List<OverdueSlabAccounts> accounts1 = new List<OverdueSlabAccounts>();
    List<OverdueSlabAccounts> accounts2 = new List<OverdueSlabAccounts>();
    List<OverdueSlabAccounts> accounts3 = new List<OverdueSlabAccounts>();

    //For T3
    accounts1.Add(new OverdueSlabAccounts()
        {
            AccountId = "JKB1",
            AccountName = "JKB1",
            SalesCode = "JKB",
            Value = "500"
        });

    accounts1.Add(new OverdueSlabAccounts()
        {
            AccountId = "JKB2",
            AccountName = "JKB2",
            SalesCode = "JKB",
            Value = "500"
        });

    overdues.Add(new OverdueModel()
    {
        Slab = "T3",
        Value = 1000,
        Percentage = 0,
        Accounts= accounts1
    });

    //For T4
    accounts2.Add(new OverdueSlabAccounts()
        {
            AccountId = "JKB1",
            AccountName = "JKB1",
            SalesCode = "JKB",
            Value = "1000"
        });

    overdues.Add(new OverdueModel()
    {
        Slab = "T4",
        Value = 1000,
        Percentage = 0,
        Accounts= accounts2
    });

    //For T5
    accounts3.Add(new OverdueSlabAccounts()
        {
            AccountId = "JKB1",
            AccountName = "JKB1",
            SalesCode = "JKB",
            Value = "1000"
        });

    accounts3.Add(new OverdueSlabAccounts()
        {
            AccountId = "JKB2",
            AccountName = "JKB2",
            SalesCode = "JKB",
            Value = "500"
        });

    accounts3.Add(new OverdueSlabAccounts()
        {
            AccountId = "JKB3",
            AccountName = "JKB3",
            SalesCode = "JKB",
            Value = "500"
        });

    overdues.Add(new OverdueModel()
    {
        Slab = "T5",
        Value = 2000,
        Percentage = 0,
        Accounts= accounts3
    });

    //Show the Current Data
    overdues.Dump();

    var result = overdues.Where(a=>a.Accounts.Any(b=>b.AccountId.Equals("JKB2")));

    result.Dump();


}

The filter is correct in terms of it is returning the OverdueModel instances that have a record;过滤器在返回具有记录的OverdueModel实例方面是正确的; the problem is that you want just the filtered part of the interior .Accounts .问题是你只想要内部的过滤部分.Accounts If we assume that we don't want to change all of the objects, you're going to need to create a projection to a new model that contains just those filtered accounts.如果我们假设我们不想更改所有对象,您将需要创建一个投影到包含那些过滤帐户的新模型。 Perhaps something like:也许是这样的:

var results = from outer in overdues
                where outer.Accounts.Any(b => b.AccountId == "JKB2")
                let filtered = outer.Accounts.FindAll(b => b.AccountId == "JKB2")
                select (Record: outer, Accounts: filtered);

although a wide range of alternatives are possible.尽管可能有多种选择。 For example, a flatter model would be:例如,更平坦的模型将是:

var results = from outer in overdues
                from account in outer.Accounts
                where account.AccountId == "JKB2"
                select (Record: outer, Account: account);

I believe what you're looking for is the SelectMany operator in LINQ, which flattens a sequence of collections.我相信您正在寻找的是 LINQ 中的 SelectMany 运算符,它可以展平一系列集合。

So try the below所以试试下面的

var result = overdues.SelectMany(a=>a.Accounts).Where(a=>a.AccountId.Equals("JKB2"))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM