有没有一种方法可以使用LINQ提取JSON字符串的内容

时间:2019-09-01 08:35:13

标签: c# json linq

我有此代码:

var jsonResponse = response.Content.ReadAsStringAsync().Result;
            List<TranslationResult> a  = JsonConvert.DeserializeObject< List<TranslationResult>>(jsonResponse);
var t0 = (a[0] != null) ? a[0] : null;
var t1 = (t0 != null) ? t0.Translations[0] : null;
var t2 = (t1 != null) ? t1.DisplayTarget : null;
var p2 = (t1 != null) ? t1.PosTag : null;

public class TranslationResult
{
    public string DisplaySource { get; set; }
    public Translation[] Translations { get; set; }
}

public class Translation
{
    public string DisplayTarget { get; set; }
    public string PosTag { get; set; }
}

我与所有null测试一起使用的代码看起来很凌乱,我想清理一下。任何人都可以建议我可以做到的方式,或者如果可能的话可以建议使用LINQ的方式。请注意,我只需要DisplayTarget和PosTag详细信息。

4 个答案:

答案 0 :(得分:3)

您只能使用LINQ来获取翻译结果和其中的翻译。您仍然需要打开DisplayTargetPosTag的包装。

List<TranslationResult> a = JsonConvert.DeserializeObject<List<TranslationResult>>(jsonResponse);
var firstTranslation = a.FirstOrDefault()?.Translations?.FirstOrDefault();
var displayTarget = firstTranslation?.DisplayTarget;
var posTag = firstTranslation?.PosTag;

此外,您可以使用C#7.0元组一次性打包多个值。

List<TranslationResult> a = JsonConvert.DeserializeObject<List<TranslationResult>>(jsonResponse);
var firstTranslation = a.FirstOrDefault()?.Translations?.FirstOrDefault();
var (displayTarget, posTag) = (firstTranslation?.DisplayTarget, firstTranslation?.PosTag);

如果您想使用所有值,而不仅仅是像示例中那样首先使用,则可以按以下方式使用LINQ:

List<TranslationResult> results = JsonConvert.DeserializeObject<List<TranslationResult>>(jsonResponse);
var translations = (results ?? Enumerable.Empty<TranslationResult>())
            .Select(x => x.Translations)
            .Where(x => x != null)
            .SelectMany(x => x)
            .Where(x => x != null)
            .Select(x => (x.DisplayTarget, x.PosTag));
foreach (var (displayTarget, posTag) in translations)
{
    // do something with displayTarget and posTag
}

答案 1 :(得分:2)

以下是使用Linq和命名元组的示例:

List<TranslationResult> a = JsonConvert.DeserializeObject<List<TranslationResult>>(jsonResponse);

IEnumerable<(string DisplayTarget, string PosTag)> tuples = 
  a.Where(t0 => t0?.Translations ?? false)
    .SelectMany(
      t0 => t0.Translations.Select(
        t1 => (DisplayTarget: t1?.DisplayTarget ?? string.Empty, PosTag: t1?.PosTag ?? string.Empty)));

// Iterate over the result of named tuples
foreach ((string DisplayTarget, string PosTag) tuple : tuples)
{
  // Values are string.Empty when they returned null from deserialization
  var displayTarget = tuple.DisplayTarget;
  var posTag = tuple.PosTag;
}

答案 2 :(得分:1)

var t0 = (a[0] != null) ? a[0] : null;

可以更改为

var t0 = a[0];

因为结果是相同的。还有

var t1 = (t0 != null) ? t0.Translations[0] : null;
var t2 = (t1 != null) ? t1.DisplayTarget : null;
var p2 = (t1 != null) ? t1.PosTag : null;

可以更改为

var t1 = t0?.Translations[0];
var t2 = t1?.DisplayTarget;
var p2 = t1?.PosTag;

使用null condition operator是“如果不为null,则返回否则为null”检查的缩写。

答案 3 :(得分:1)

query可能会更容易:

 string PosTag = (string)JToken.Parse(jsonResponse).SelectToken("$..PosTag");