C# LINQ 从字符串数组中选择元素

Posted

技术标签:

【中文标题】C# LINQ 从字符串数组中选择元素【英文标题】:C# LINQ to select element from string array 【发布时间】:2022-01-01 13:51:48 【问题描述】:

我有一个字符串:

private const string Codes = "2,10";

public void method()

    var displayCodes = Codes.Split(',');
    DemoResponse response = webService.GetResponse();  //getting response from API

    if(response.Errors.Any(x => displayCodes.Contains(x.StackTrace))
    
         int myCode = int.Parse(response.Errors.Select(x => x.StackTrace).FirstOrDefault());
    

这是“DemoResponse”模型:

public class DemoResponse

     public bool Validate  get; set; 
     public IEnumerable<ErrorResponse> Errors  get; set; 


public class ErrorResponse

     public string Message  get; set; 
     public string StackTrace  get; set; 

来自 API 的 DemoResponse“响应”返回结果为:(例如)

  
    "Validate" : false,
    "Errors" : 
             
                "Message" : "test1",
                "StackTrace" : "2"
             
  
   
     "Validate" : false,
     "Errors" : 
             
                "Message" : "test1",
                "StackTrace" : "2"
             
  
   
     "Validate" : false,
     "Errors" : 
             
                "Message" : "test1",
                "StackTrace" : "95"
             
  

DemoResponse "response" 将始终仅包含来自 const string "Codes" 的代码之一,即 2 或 10。但可能包含其他代码。

如果 DemoResponse "response" 包含代码 2 作为第一个代码,则此行可以正常工作:

int myCode = int.Parse(response.Errors.Select(x => x.StackTrace).FirstOrDefault());

但如果 DemoResponse“响应”没有代码 2 作为第一个,那么我如何编写一个 LINQ 来选择代码 2 并分配给“myCode”变量? 例如:

  "StackTrace" : "95",
  "StackTrace" : "95",
  "StackTrace" : "2"

【问题讨论】:

您需要使用Where 方法并反转解析代码以完全不处理“2”。 int myCode = response.Errors.Where(e =&gt; e.StackTrace == "2").Select(e =&gt; int.Parse(e.StackTrace)).FirstOrDefault(); - 对于任一可能的代码,请执行 int myCode = response.Errors.Where(e =&gt; displayCodes.Contains(e.StackTrace)).Select(e =&gt; int.Parse(e.StackTrace)).FirstOrDefault(); 注意:如果两个代码都不存在,则您不需要 ifmyCode 将是 0 【参考方案1】:

需要在if条件里面为每个循环添加。

private const string Codes = "2,10";

public void method()

    var displayCodes = Codes.Split(',');
    DemoResponse response = webService.GetResponse();  //getting response from API

    if(response.Errors.Any(x => displayCodes.Contains(x.StackTrace))
    
        foreach (ErrorResponse item in response.Errors)
        
          // write your logic based on your requirement

          if(int.Parse(item.StackTrace) == 2)
          
          int myCode = int.Parse(item.StackTrace);
          
        
    

【讨论】:

我只能为“myCode”变量设置一个值。我试过这个 - int myCode = int.Parse(response.Errors .Where(x =&gt; displayCodes.Contains(x.StackTrace)).Select(x =&gt; x.StackTrace).FirstOrDefault()); 根据您的问题,需要 StackTrace=2 值作为第一优先级分配给 mycode 变量,对吗?根据您的喜好,有多种可能性 2,95,95 或 95,95,2 或 95,2,95。因此,对于您的代码中的第一个工作正常。现在对于第 2 和第 3 场景,您可以使用 foreach 和其他条件,例如 if StackTrace=2 然后分配给 mycode 否则不。检查相同的更新答案 LINQ 可以很容易地处理这个问题,foreach 循环是多余的。【参考方案2】:

在我看来,您希望从 API 接收的是一组信息,但在您的代码中,您将从 API 接收的内容映射到 @987654321 类型的单个对象@。我怀疑您实际上希望response 成为DemoResponses 的列表或数组

此外,根据我对以下问题的理解:

但如果 DemoResponse “response” 没有第一个代码 2,那么我如何编写一个 LINQ 来选择 Code 2 并分配给“myCode”变量?

,您想将第一个与Codes 中的任何代码匹配的StackTrace 值分配给myCode;而不是将 any StackTrace 值分配给 myCode

如果这两个假设是正确的,您可以尝试以下方法:

private const string Codes = "2,10";

public void method()

    var displayCodes = Codes.Split(',');

    // NOTE: response is now an array of DemoResponse; 
    // GetResponse()'s implementation and return type may need to be rewritten accordingly
    DemoResponse[] response = webService.GetResponse();

    var errors = response.SelectMany(r => r.Errors);
    
    if (errors.Any(x => displayCodes.Contains(x.StackTrace)))
    
        int myCode = int.Parse(errors.Select(x => x.StackTrace).First(s => displayCodes.Contains(s)));
    

或者,您可以循环查看堆栈跟踪而不是错误:

var stackTraces = response.SelectMany(r => r.Errors).Select(e => e.StackTrace);
    
if (stackTraces.Any(s => displayCodes.Contains(s)))

    int myCode = int.Parse(stackTraces.First(s => displayCodes.Contains(s)));

【讨论】:

以上是关于C# LINQ 从字符串数组中选择元素的主要内容,如果未能解决你的问题,请参考以下文章

C#字符串数组替换最后一个元素

如何从列表数组(linq 列表)C# 中的所有元素调用方法

C# LINQ 从数组/列表中不包含值的位置选择

用于检查字符串列表/数组中的字符串的 C# 最佳实践 (LINQ) [关闭]

在 C# 中使用 LINQ 在字符串数组中查找确切的子字符串

将 linq 查询转换为字符串数组 - C#