C# 从 List<KeyValuePair<string,string>> 返回匹配项
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1793472/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Returning a match from a List<KeyValuePair<string,string>>
提问by Jamie Keeling
I currently have a class that uses the KeyValuePair
with List
to store a collection of tracks in the format of Key = track, Value = artist.
我目前有一个类,它使用KeyValuePair
withList
以 Key = track, Value = Artist 的格式存储曲目集合。
I'm trying to provide a way of searching for a particular track and if there are any matches then return the entire matching CD.
我正在尝试提供一种搜索特定曲目的方法,如果有任何匹配项,则返回整个匹配的 CD。
This is my attempt so far:
到目前为止,这是我的尝试:
public CompilationCD FindTrackInComCD(string track)
{
CompilationCD temp = new CompilationCD();
List<CD> tempComCols = _cdCollection.FindAll(delegate(CD cd)
{ return cd.GetType() == temp.GetType(); });
foreach (KeyValuePair<string, string> comCD in tempComCols)
{
if (comCD.Key.Contains(track))
{
return comCD;
}
}
throw new ArgumentException("No matches found");
}
I have a collection of Cd's of type CD (List<CD>
) therefore I create a new List<>
of the appropiate type by comparing it to the temp List.
我有一个 CD ( List<CD>
)类型的 Cd 集合,因此我List<>
通过将它与临时列表进行比较来创建一个新的适当类型。
When compiling I get the following errors:
编译时出现以下错误:
Cannot convert type 'CDCollection.CD' to System.Collections.Generic.KeyValuePair<string,string>'
Cannot implicitly convert type 'System.Collections.Generic.KeyValuePair<string,string>'
(CDCollection is my project namespace and CD/CompilationCD are the classes)
(CDCollection 是我的项目命名空间,CD/CompilationCD 是类)
Sorry for this seeming like a similar question to one I've previously asked. I tried to use the methods I was given before but I'm a bit stumped; I've not used List<>
or KeyValuePair
very often.
抱歉,这似乎是我之前问过的一个类似问题。我尝试使用之前给出的方法,但我有点难住;我没有使用List<>
或KeyValuePair
经常使用。
This is the CD Class:
这是CD类:
using System;
using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text;
使用 System.Collections; 使用 System.Collections.Generic; 使用 System.Linq;使用 System.Text;
namespace CDCollection { public class CD { #region Fields private readonly string _artist; private readonly string _album; private List _track = new List(); #endregion
命名空间 CDCollection { public class CD { #region Fields private readonly string _artist; 私有只读字符串_album;私人列表 _track = 新列表();#endregion
#region Constructors
public CD()
{
_artist = "";
_album = "";
_track = null;
}
public CD(string albumName)
{
_album = albumName;
}
public CD(string artistName, string albumName)
{
_artist = artistName;
_album = albumName;
}
#endregion
#region Properties
/// <summary>
/// Get/Set Artist Name
/// </summary>
public virtual string Artist
{
get
{
return _artist;
}
set
{
value = _artist;
}
}
/// <summary>
/// Get/Set Album
/// </summary>
public string Album
{
get
{
return _album;
}
set
{
value = _album;
}
}
/// <summary>
/// Get/Set Track Name
/// </summary>
public virtual List<string> Track
{
get
{
return _track;
}
set
{
value = _track;
}
}
#endregion
#region ToString()
/// <summary>
/// Custom ToString() Method
/// </summary>
/// <returns></returns>
public override string ToString()
{
//Create new StringBuilder object
StringBuilder sb = new StringBuilder();
sb.Append("Artist Name");
//Display error if Artist is not available
if (_artist == null || _artist == "")
{
sb.Append("\nNo Artist Entered");
}
else
{
sb.Append("\n" + this._artist);
}
sb.Append("\n");
sb.Append("\nAlbum Name");
//Display error if Album is not available
if (_album == null || _album == "")
{
sb.Append("\nNo Album Entered");
}
else
{
sb.Append("\n" + this._album);
}
sb.Append("\n");
sb.Append("\nTrack Name");
sb.Append("\n");
//Iterate through all tracks stored in list
foreach (string trackName in _track)
{
//Print each artist
sb.Append("\n" + trackName);
}
sb.Append("\nEnd of CD Record.........");
return sb.ToString();
}
#endregion
}
}
}
This is the CompilationCD class:
这是 CompilationCD 类:
using System;
using System.Collections.Generic; using System.Linq; using System.Text;
使用 System.Collections.Generic; 使用 System.Linq;使用 System.Text;
namespace CDCollection { public class CompilationCD : CD { #region Fields
命名空间 CDCollection { 公共类 CompilationCD : CD { #region 字段
private readonly string _artist;
private readonly string _album;
private List<KeyValuePair<string,string>> _tracks = new List<KeyValuePair<string,string>>();
//List<KeyValuePair> Reference.
//http://msdn.microsoft.com/en-us/library/6sh2ey19(VS.85).aspx
#endregion
#region Constructors
public CompilationCD()
{
_album = "";
_artist = "Various Artists";
}
public CompilationCD(string albumName):base(albumName)
{
_album = albumName;
_artist = "Various Artists";
}
#endregion
public void AddTracks(string track, string artist)
{
_tracks.Add(new KeyValuePair<string, string>(track, artist));
}
#region Properties
public override string Artist
{
get
{
return this._artist;
}
}
public new List<KeyValuePair<string,string>> Track
{
get
{
return _tracks;
}
set
{
_tracks = value;
}
}
#endregion
#region ToString()
//TEST
public override string ToString()
{
//Create new StringBuilder object
StringBuilder sb = new StringBuilder();
sb.Append("Artist Name");
//Display error if Artist is not available
if (_artist == null || _artist == "")
{
sb.Append("\nNo Artist Entered");
}
else
{
sb.Append("\n" + this._artist);
}
sb.Append("\n");
sb.Append("\nAlbum Name");
//Display error if Album is not available
if (base.Album == null || base.Album == "")
{
sb.Append("\nNo Album Entered");
}
else
{
sb.Append("\n" + base.Album);
}
sb.Append("\n");
sb.Append("\nTrack Name");
sb.Append("\n");
////Iterate through all tracks stored in list
//foreach (string trackName in base.Track)
//{
// //Print each artist
// sb.Append("\n" + trackName);
//}
for(int i = 0; i <= _tracks.Count; i++)
{
string track = _tracks[i].Key;
string artist = _tracks[i].Value;
sb.Append("\nTrack");
sb.Append(track);
sb.Append("\nArtist");
sb.Append(artist);
}
sb.Append("\nEnd of Compilation CD Record.........");
return sb.ToString();
}
#endregion
}
}
}
I have strict rules that mean i have to inherit from CD to create my CompilationCD as well as using a List> for my track collection, it needs to hold both a track and artist. Crazy i know =/
我有严格的规则,这意味着我必须从 CD 继承来创建我的 CompilationCD 以及使用 List> 作为我的曲目集合,它需要同时保存曲目和艺术家。疯了我知道=/
Furthermore i must store ALL types of cd in a list of type CD ( List ).
此外,我必须将所有类型的 cd 存储在类型 CD( List )的列表中。
采纳答案by Dathan
The problem is in your foreach
loop. tempComCols
is a List<CD>
, but comCD
is a KeyValuePair<string, string>
. So, your loop results in an invalid type conversion.
问题出在你的foreach
循环中。 tempComCols
是List<CD>
,但comCD
是KeyValuePair<string, string>
。因此,您的循环会导致无效的类型转换。
Unfortunately, since we don't know what the CD
class (interface?) looks like, I can't suggest a fix in terms of its properties.
不幸的是,由于我们不知道CD
类(接口?)是什么样子,我不能建议修复它的属性。
EDIT:The following is perhaps a better version of your method (though, I haven't debugged it correctly):
编辑:以下可能是您方法的更好版本(不过,我没有正确调试它):
public CompilationCD FindTrackInComCD(string track)
{
CompilationCD temp = new CompilationCD();
temp = _cdCollection.Where(cd => cd is CompilationCD)
.Cast<CompilationCD>()
.Where(com_cd => com_cd.Tracks.ContainsKey(track))
.FirstOrDefault();
if (temp != null)
return temp;
else throw new ArgumentException("No matches found");
}
You can't cast a CompilationCD
to a KeyValuePair<string, string>
, so we just use the CompilationCD
class directly. We can pass off the responsibility for searching the track list to the IEnumerable<T>
extenion methods provided by System.Linq
, which makes this method very easy.
您不能将 a 转换CompilationCD
为 a KeyValuePair<string, string>
,因此我们直接使用CompilationCD
该类。我们可以将搜索曲目列表的责任IEnumerable<T>
交给 提供的扩展方法System.Linq
,这使得该方法非常简单。
回答by McKay
Why not use a dictionary? They are a list of key value pairs, but provide easy access via the key.
为什么不使用字典?它们是一个键值对列表,但可以通过键轻松访问。
回答by André Pena
that's because tempComCols
will return CD
and not KeyValuePair<string, string>
那是因为tempComCols
会回来CD
而不是KeyValuePair<string, string>
回答by Michael Myers
Your List
doesn't contain KeyValuePairs
, so you can't loop through it as if it did. Try something like this:
你的List
不包含KeyValuePairs
,所以你不能像它那样循环遍历它。尝试这样的事情:
foreach (CD comCD in tempComCols)
{
if (comCD.MyKeyValueProp.Key.Contains(track))
{
return comCD;
}
}
But as McKay said, if your CD
class does nothing but encapsulate a KeyValuePair
, a Dictionary
would be much easier.
但正如 McKay 所说,如果你的CD
类只封装 a KeyValuePair
, aDictionary
会容易得多。
回答by bitbonk
tempComCols is list of CD
items: List<CD> tempComCols ...
and you want to iterate over something that is of type IEnumerable: foreach (KeyValuePair<string, string> comCD in tempComCols)
tempComCols 是CD
项目列表:List<CD> tempComCols ...
并且您想要迭代 IEnumerable 类型的内容:foreach (KeyValuePair<string, string> comCD in tempComCols)
回答by SLaks
You are enumerating a List<CD>
and assigning to a KeyValuePair<string, string>
.
您正在枚举 aList<CD>
并分配给 a KeyValuePair<string, string>
。
You can rewrite your method using LINQ in C# 3 like this:
您可以在 C# 3 中使用 LINQ 重写您的方法,如下所示:
public CompilationCD FindTrackInComCD(string track) {
return _cdCollection.OfType<CompilationCD>().FirstOrDefault(cd => cd.Name.Contains(track, StringComparison.CurrentCultureIgnoreCase));
}
By the way, you can get the System.Type
object for CompilationCD
by writing typeof(CompilationCD)
; you don't need to call GetType()
.
顺便说一句,您可以通过编写获取System.Type
对象;你不需要打电话。CompilationCD
typeof(CompilationCD)
GetType()
回答by dtroy
you can use:
{cd is CompilationCD};
instead of
{ return cd.GetType() == temp.GetType(); });
if I understand correctly and CD is some sort of Dictionary, you can rewrite the function as:
public CompilationCD FindTrackInComCD(string track) { return (CompilationCD)_cdCollection.Find(delegate(CD cd) { return (cd is CompilationCD) && (cd.Contains(track))}); }
您可以使用:
{cd is CompilationCD};
代替
{ return cd.GetType() == temp.GetType(); });
如果我理解正确并且 CD 是某种字典,您可以将函数重写为:
public CompilationCD FindTrackInComCD(string track) { return (CompilationCD)_cdCollection.Find(delegate(CD cd) { return (cd is CompilationCD) && (cd.Contains(track))}); }
回答by Rohit
Use KeyedCollection http://msdn.microsoft.com/en-us/library/ms132438.aspx
使用 KeyedCollection http://msdn.microsoft.com/en-us/library/ms132438.aspx