繁体   English   中英

C# Lambda 用于遍历嵌套对象的表达式

[英]C# Lambda Expression for iterating through nested objects

我有以下 JSON ,我已将其反序列化为 C# object 并希望在每次迭代中提取INFO_CARD_IDDOCUMENT_NUMREVISION_NM的值

{
    "result": {
        "message": "Successfully performed search",
        "columnlist": "INFO_CARD_ID,DOCUMENT_NUM,REVISION_NM,
        "recordcount": 2,
        "rows": [
            {
                "columns": [
                    {
                        "value": "UJ3P25HO3JBPLJZ2HU",
                        "key": "INFO_CARD_ID"
                    },
                    {
                        "value": "DOC1",
                        "key": "DOCUMENT_NUM"
                    },
                    {
                        "value": "05",
                        "key": "REVISION_NM"
                    }
                ]
            },
            {
                "columns": [
                    {
                        "value": "JWQ5TCIV4JC2BCQ4C5",
                        "key": "INFO_CARD_ID"
                    },
                    {
                        "value": "DOC2",
                        "key": "DOCUMENT_NUM"
                    },
                    {
                        "value": "05",
                        "key": "REVISION_NM"
                    }
                ]
            }
        ]
    }
}

以下是 C# 类:

    public class Columns
    {
        public string value { get; set; }
        public string key { get; set; }
    }

    public class Rows
    {
        public IList<Columns> columns { get; set; }
    }

    public class Result
    {
        public string message { get; set; }
        public string columnlist { get; set; }
        public int recordcount { get; set; }
        public IList<Rows> rows { get; set; }
    }

    public class searchOutputModel
    {
        public Result result { get; set; }
    }

到目前为止,我一直在尝试使用以下表达式提取列表中的信息,但没有运气,因为每次迭代都会存储单个值,而不是同时存储每次迭代的所有值。

searchResponse = JsonConvert.DeserializeObject<searchOutputModel>(json);

var dynamicList = searchResponse.result.rows.SelectMany(x => x.columns).Where(y => y.key.Contains("INFO_CARD_ID") || y.key.Contains("DOCUMENT_NUM") || y.key.Contains("REVISION_NM")).Select(y => {
        dynamic myValue;
        if (y.key.Contains("INFO_CARD_ID"))
            myValue = new { INFO_CARD_ID = y.value };
        else if (y.key.Contains("DOCUMENT_NUM"))
            myValue = new { DOCUMENT_NUM = y.value };
        else
            myValue = new { REVISION_NM = y.value };
        return myValue;
    }).ToList();

预期 output:

INFO_CARD_ID       DOCUMENT_NUM  REVISION_NM
---------------------------------------------
UJ3P25HO3JBPLJZ2HU DOC1          05
JWQ5TCIV4JC2BCQ4C5 DOC2          05

我知道我在迭代方面做错了,因为它在每个 select 处创建了新列表,但我不确定如何实现我正在寻找的解决方案。 任何帮助表示赞赏。

我们只需要 select 每row一个 object ,这里不需要SelectMany 可以使用columns.FirstOrDefault每个属性。

我建议您为此创建一个适当的 class 而不是使用dynamic ,但这与下面的逻辑几乎没有区别。

不知道你为什么在column.key检查中使用Contains ,我使用过==

var dynamicList = searchResponse.result.rows.Select(r => 
    new {
        INFO_CARD_ID = r.columns.FirstOrDefault(c => c.key == "INFO_CARD_ID")?.value,
        DOCUMENT_NUM = r.columns.FirstOrDefault(c => c.key == "DOCUMENT_NUM")?.value,
        REVISION_NM = r.columns.FirstOrDefault(c => c.key == "REVISION_NM")?.value,
    }).ToList();

如果将每个Rows object 转换为Dictionary ,则可以使用Dictionary创建对象:

var ans = searchResponse.result.rows
            .Select(r => r.columns.ToDictionary(c => c.key, c => c.value))
            .Select(cd => new {
                INFO_CARD_ID = cd["INFO_CARD_ID"],
                DOCUMENT_NUM = cd["DOCUMENT_NUM"],
                REVISION_NM = cd["REVISION_NM"]
            });

暂无
暂无

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

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