首页 > 解决方案 > 如何从 txt 文件中找到特定的 json 元素数据列表?

问题描述

我有一个文本文件,其中包含近百万条 json 格式的记录。喜欢

[{"ev":"AM","sym":"TMHC","v":1000,"av":74917,"op":18.92,"vw":19.1305,"o":19.13,"c":19.15,"h":19.15,"l":19.13,"a":19.143,"z":90,"n":1,"s":1549380300000,"e":1549380360000},{"ev":"AM","sym":"AAPL","v":7103,"av":184266,"op":35.27,"vw":35.3148,"o":35.3264,"c":35.34,"h":35.34,"l":35.3258,"a":35.3345,"z":710,"n":1,"s":1549380300000,"e":1549380360000}]
[{"ev":"AM","sym":"VB","v":213,"av":98285,"op":149.75,"vw":150.0575,"o":150.2104,"c":150.2104,"h":150.2104,"l":150.2104,"a":150.1944,"z":35,"n":1,"s":1549380300000,"e":1549380360000}]

所以我需要从包含 AAPL 的文件中找到 json 元素列表。就像我将通过 AAPL 一样,它必须从整个文件中提供 AAPL 的 json 元素列表。

{"ev":"AM","sym":"AAPL","v":7103,"av":184266,"op":35.27,"vw":35.3148,"o":35.3264,"c":35.34,"h":35.34,"l":35.3258,"a":35.3345,"z":710,"n":1,"s":1549380300000,"e":1549380360000}

那么我怎样才能找到它呢?我正在尝试为此使用 JSONPATH,但是在 JObject 转换时它会给出错误,例如

从 JsonReader 读取 JObject 时出错

我已经为它申请了以下代码:

const string filePath = @"D:\Aggregate_Minute_AAPL.json";
string text = System.IO.File.ReadAllText(filePath);
Newtonsoft.Json.Linq.JArray jsonArray = Newtonsoft.Json.Linq.JArray.Parse(text);
var json = Newtonsoft.Json.Linq.JObject.Parse(jsonArray.ToString());
var title = json.SelectToken("$.ev.sym[*]");
Console.WriteLine(title.First());

标签: c#json

解决方案


您需要获取所有数组,无论它们是全部还是一行或每个数组都在新行上,然后将每个数组解析为JArray,然后使用所需键找到您的属性并获取该键的相应对象

public static List<JObject> GetObjectByValue(string filePath, string matchValue)
{
    var text = File.ReadAllText(filePath);

    var pattern = @"\[(.*?)\]";

    var matches = Regex.Matches(text, pattern);

    var result = matches.Cast<Match>()
            .Select(a => JArray.Parse(a.Value))
            .Select(b => b.ToObject<JObject[]>())
            .Where(x => x.Properties()
                         .Any(y => y.Name == "sym" && y.Value.ToString() == matchValue))
                         .FirstOrDefault()
            .ToList();

    return result;
}

用法:

var list_obj = GetObjectByValue(@"Path to your text file", "VB");

编辑1:

如果您想通过使用获取匹配对象,Parallel.For则可以使用以下函数,

public static List<JObject> GetObjectByValue(string filePath, string matchValue)
{
    var text = File.ReadAllText(filePath);

    var pattern = @"\[(.*?)\]";

    var matches = Regex.Matches(text, pattern);

    List<JObject> jObjects = new List<JObject>();

    Parallel.For(0, matches.Count, i =>
    {
        JArray jArray = JArray.Parse(matches[i].Value);
        var res = jArray.ToObject<JObject[]>().Where(x => x.Properties().Any(y => y.Name == "sym" && y.Value.ToString() == matchValue)).ToList();
        jObjects.AddRange(res);
    });

    return jObjects;
}

推荐阅读