首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >复杂Json类型查询

复杂Json类型查询
EN

Stack Overflow用户
提问于 2015-10-09 22:15:25
回答 1查看 70关注 0票数 0

我从另一个外部供应商那里获得了JSON,我在这里简化了相同的内容。

问题:我在json中搜索instrumentIdentifier,必须提取它,它可以出现在资产类别中的第2级、第3级或第4级。

我不知道如何使用linq或普通的C#方法正确地搜索它,我没有最新的基于JsonPath的newtonsoft查询。很难用Linq甚至普通的方法,

.net版本为4.0,newtonsoft 4.5

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-10-10 00:13:10

使用递归:

代码语言:javascript
复制
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);
}

这将进行深度优先搜索。

如果您想要一个遍历树结构的更通用的解决方案,那么我创建这些扩展方法是为了我自己的利益:

代码语言:javascript
复制
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;
        }
    }
}

这将允许您这样做:

代码语言:javascript
复制
var theHolding = portfolio.assetTypes
    .Recurse(a => a.assetTypes)
    .SelectMany(a => a.holdings.OrEmpty())
    .FirstOrDefault(h => h.instrumentIdentifier == "foo");
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33047904

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档