简体   繁体   English

复杂的Json类型查询

[英]Complex Json type Querying

I get the JSON from another external vendor and I have simplyfied the same here. 我从其他外部供应商那里获得了JSON,在这里我已经简单地确定了它。

Problem : I am searching for instrumentIdentifier in Holding in the json, have to extract it , it can appear at level 2 or level 3 or level 4 in the assetcategory. 问题:我正在json的Holding中搜索instrumentIdentifier,必须将其提取出来,它可以出现在资产类别的第2级或第3级或第4级。

I am not sure how to search it properly using linq or normal C# methods, I don't have latest newtonsoft to query based on JsonPath. 我不确定如何使用linq或常规C#方法正确搜索它,我没有最新的newtonsoft基于JsonPath进行查询。 Stuck badly using Linq or even normal method, 用Linq甚至常规方法都严重卡住了,

.net version is 4.0 , newtonsoft 4.5 .net版本是4.0,newtonsoft 4.5

Use recursion: 使用递归:

public holdings FindHoldings(portfolio portfolio, string instrumentId) 
{
    return FindHoldingsRecursive(portfolio.assetTypes, instrumentId);
}

public holdings FindHoldingsRecursive(
    IEnumerable<subAssetType> assetTypes,
    string instrumentId)
{
    if (assetTypes == null)
        return null;

    return assetTypes
      .Select(a => FindHoldingsRecursive(a, instrumentId))
      .FirstOrDefault(h => h != null);
}

public holdings FindHoldingsRecursive(
    subAssetType assetType, 
    string instrumentId)
{
    return 
        assetType.holdings.FirstOrDefault(h => h.instrumentIdentifier == instrumentId);
        ?? FindHoldingsRecursive(assetType.assetTypes, instrumentId);
}

This will do a depth-first search. 这将进行深度优先搜索。

If you want a more generic solution to traversing a tree structure, I'd created these extension method for my own benefit: 如果您希望使用更通用的遍历树结构的解决方案,则出于自己的利益创建了这些扩展方法:

public static class EnumerableExtensions
{
    public static IEnumerable<T> OrEmpty<T>(this IEnumerable<T> collection)
    {
        return collection ?? Enumerable.Empty<T>();
    }

    public static IEnumerable<T> Recurse<T>(
        this IEnumerable<T> collection, 
        Func<T, IEnumerable<T>> childrenSelector)
    {
        return collection.SelectMany(i => i.Recurse(childrenSelector));
    }

    public static IEnumerable<T> Recurse<T>(
        this T parent, 
        Func<T, IEnumerable<T>> childrenSelector)
    {
        yield return parent;
        var children = childrenSelector(parent).OrEmpty();
        foreach (var descendant in children.Recurse(childrenSelector))
        {
            yield return descendant;
        }
    }
}

This will let you do this: 这将使您执行此操作:

var theHolding = portfolio.assetTypes
    .Recurse(a => a.assetTypes)
    .SelectMany(a => a.holdings.OrEmpty())
    .FirstOrDefault(h => h.instrumentIdentifier == "foo");

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

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