Returning a match from a List<KeyValuePair<string,string>>
Solution 1
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.
Unfortunately, since we don't know what the CD
class (interface?) looks like, I can't suggest a fix in terms of its properties.
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.
Solution 2
Why not use a dictionary? They are a list of key value pairs, but provide easy access via the key.
Comments
-
Jamie Keeling over 3 years
I currently have a class that uses the
KeyValuePair
withList
to store a collection of tracks in the format of 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.
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 newList<>
of the appropiate type by comparing it to the temp 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)
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<>
orKeyValuePair
very often.This is the CD Class:
using System;
using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text;
namespace CDCollection { public class CD { #region Fields private readonly string _artist; private readonly string _album; private List _track = new List(); #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:
using System;
using System.Collections.Generic; using System.Linq; using System.Text;
namespace CDCollection { public class CompilationCD : CD { #region Fields
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 =/
Furthermore i must store ALL types of cd in a list of type CD ( List ).