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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 20:53:35  来源:igfitidea点击:

Returning a match from a List<KeyValuePair<string,string>>

c#listforeach

提问by Jamie Keeling

I currently have a class that uses the KeyValuePairwith Listto store a collection of tracks in the format of Key = track, Value = artist.

我目前有一个类,它使用KeyValuePairwithList以 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 KeyValuePairvery 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 foreachloop. tempComColsis a List<CD>, but comCDis a KeyValuePair<string, string>. So, your loop results in an invalid type conversion.

问题出在你的foreach循环中。 tempComColsList<CD>,但comCDKeyValuePair<string, string>。因此,您的循环会导致无效的类型转换。

Unfortunately, since we don't know what the CDclass (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 CompilationCDto a KeyValuePair<string, string>, so we just use the CompilationCDclass 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 tempComColswill return CDand not KeyValuePair<string, string>

那是因为tempComCols会回来CD而不是KeyValuePair<string, string>

回答by Michael Myers

Your Listdoesn'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 CDclass does nothing but encapsulate a KeyValuePair, a Dictionarywould be much easier.

但正如 McKay 所说,如果你的CD类只封装 a KeyValuePair, aDictionary会容易得多。

回答by bitbonk

tempComCols is list of CDitems: 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.Typeobject for CompilationCDby writing typeof(CompilationCD); you don't need to call GetType().

顺便说一句,您可以通过编写获取System.Type对象;你不需要打电话。CompilationCDtypeof(CompilationCD)GetType()

回答by dtroy

  1. you can use:

    {cd is CompilationCD};
    

    instead of

    { return cd.GetType() == temp.GetType(); });
    
  2. 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))});
    }
    
  1. 您可以使用:

    {cd is CompilationCD};
    

    代替

    { return cd.GetType() == temp.GetType(); });
    
  2. 如果我理解正确并且 CD 是某种字典,您可以将函数重写为:

    public CompilationCD FindTrackInComCD(string track)
    {
        return (CompilationCD)_cdCollection.Find(delegate(CD cd)
        { return (cd is CompilationCD) && (cd.Contains(track))});
    }