【问题标题】:Find string value in comma-separated list在逗号分隔的列表中查找字符串值
【发布时间】:2016-04-13 23:37:30
【问题描述】:

我有一个列表(字符串),其成员形式为“标签,位置”;标签是不同的。我需要一个接受标签参数并返回位置的方法。

我可以使用 foreach 进行迭代以找到正确的标签,然后使用 Split 操作列表成员以返回位置。但是我确信有更好的方法,大概是使用 LINQ,类似于

return theList.Single(x => x == theLabel);

但这不起作用,因为列表值 == label,location。

【问题讨论】:

  • theList 是字符串列表吗?
  • 为什么不使用字典
  • 是的,该列表是一个字符串列表,例如:label1,location1 然后 label2,location2。至于使用字典,我并不反对,但遍历列表已经非常简单了。我希望有一个或两行 LINQ 选项。
  • @xnguyeng 迭代字典同样简单,查找不需要 linq,字典当然是你应该这样做的方式。

标签: c# linq


【解决方案1】:

请看下面的代码:

string get_location(List<string> list, label)
{
  return list.Select(s => s.Split(',')).ToDictionary(s => s[0], s => s[1])[label];
}

如果同一个列表上有多个请求,那么最好保存那个字典,然后对所有查询的标签重复使用:

var map = list.Select(s => s.Split(',')).ToDictionary(s => s[0], s => s[1]);

或者:

var map = new Dictionary<string, string>();
list.ForEach(s => { var split = s.Split(','); map.Add(split[0], split[1]); });

【讨论】:

  • 这看起来很完美,谢谢。 [label] 最后的作用是什么?不是在第一个 lambda 表达式中分配的键和值吗?
  • [label] 在 Dictionary 中找到 Key == label 对应的 Value。
  • 啊,当然,谢谢。虽然其他人建议完全跳过列表(因为源是 csv)并直接进入字典,但您首先对我未完全描述的问题给出了正确答案。
【解决方案2】:

由于标签是唯一的,您可以考虑将您的数据转换为dictionary&lt;string,string&gt;。您可以将标签保留为 key,将位置保留为 value

var lableLocatonDict = theList.Select(item => item.Split(','))
                                      .ToDictionary(arr => arr[0], arr => arr[1]);

现在要访问特定标签(键)的位置(值),您只需这样做

var location = lableLocatonDict["LabelToCheck"];

如果要在访问之前检查字典中是否存在项目,可以使用 ContainsKey 方法。

if(lableLocatonDict.ContainsKey("LabelToCheck"))
{
    var location = lableLocatonDict["LabelToCheck"];
}

或者TryGetValue

var location = string.Empty;
if(lableLocatonDict.TryGetValue("LabelToCheck",out location))
{
   // location will have the value here             
}

【讨论】:

  • 判断他的其他问题,它的托管数据,所以他应该立即将其存储为 dict 并放弃列表和转换。
  • 我完全同意@Wobbles。
  • 您是正确的@Wobbles,这些值存储在格式良好且结构化的 csv 文件中。我已经有了一种将 csv 读入列表的方法,所以我从那里开始。也许我应该问一个新的/更好的问题:如何将 csv 直接读入字典:)。
  • @xnguyeng 见下文,如果它是 CSV,我建议放弃我们所说的一切并使用某种Enumerable&lt;T&gt; 此外,如果 CSV 是仅来自您的数据并由您使用的数据应用程序,有更好更简单的序列化格式,我最近开始偏爱 JSON。
【解决方案3】:

正如我和其他 2 个答案所建议的那样,Dictionary 正是为此目的而设计的。您表达了对迭代 dict 而不是列表的担忧,认为迭代可能更困难,但实际上它更容易,因为不需要拆分(而且速度更快)。

Dictionary<String,String> locations = new Dictionary<String,String>();

//How to add locations
locations.Add("Sample Label","Sample Location");

//How to modify a location
locations["Sample Label"] = "Edited Sample Locations";

//Iterate locations
foreach (var location in locations)
{
    Console.WriteLine(location.key);
    Console.WriteLine(location.value);
}

我什至会更进一步说,为了将来证明您的应用程序并添加在每个位置存储更多信息的能力,您真的应该使用ObservableCollection&lt;T&gt;,其中T 是一个自定义类对象:

public class LocationInfo
{
    String Label {get;set;}
    String Location {get;set;}
    String Description {get;set;}
}

ObservableCollection<LocationInfo> Locations = new ObservableCollection<LocationInfo>();

【讨论】:

  • 谢谢@Wobbles 我会看看我是否可以按照您描述的方式实现。
猜你喜欢
  • 2014-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多