你能根据列表中对象的属性从集合中随机选择一个列表成员吗



我写了一个程序来洗牌文件夹中的媒体,因为我拥有的媒体播放器虽然支持洗牌,但不记得已经播放了什么,所以很多时候我都会重复。我写了我自己的,以确保每件事都至少玩一次。所以不管怎样,我做了一个物体来保存视频信息:

namespace MediaShuffler {
class Video {
public string filepath {get; set;}
public string filename {get; set;}
public string filetype {get; set;}
public string fullfile {get; set;}
public bool played {get; set;}
override
public bool Equals(object checkobj) {
if (!(checkobj is Video)) return false;
return ((Video)checkobj).fullfile == fullfile;
}
public Video(string file) {
fullfile = file;
filepath = Path.GetDirectoryName(file);
filename = Path.GetFileName(file);
filetype = Path.GetExtension(file).ToLower();
played = false;
}
public void Play() {
if (!Utils.cfg.ContainsKey("mediaplayer.executable") || 
!Utils.cfg.ContainsKey("mediaplayer.executable")) return;
Process proc = new Process();
proc.StartInfo.FileName = Utils.cfg["mediaplayer.executable"];
proc.StartInfo.WorkingDirectory = Utils.cfg["mediaplayer.directory"];
proc.StartInfo.Arguments = Utils.TokenizeArguments(GetTokens());
proc.Start();
played = true;
proc.WaitForExit();
OnVideoComplete(EventArgs.Empty);
}
private Dictionary<string, string> GetTokens() {
Dictionary<string, string> tokens = new Dictionary<string, string>();
tokens.Add("%filename%", filename);
tokens.Add("%filepath%", filepath);
tokens.Add("%filetype%", filetype);
return tokens;
}
protected virtual void OnVideoComplete(EventArgs e) {
EventHandler<EventArgs> handler = VideoComplete;
if (handler != null) handler(this, e);
}
public event EventHandler<EventArgs> VideoComplete;
}
}

在程序的主要部分中,我对传递给程序的路径进行迭代,并构建一个List"播放列表";文件夹中所有视频文件的。在我制作了这个对象之后,我意识到我实际上不知道一种有效的方法来获得一个随机列表成员,其中成员#hasPlayed是false。我最终做的是:

while (true) {
int selection = new Random().Next(0, playlist.Count-1);
videoPlaying = true;
Write("[" + selection.ToString() + " / " + playlist.Count.ToString() + "] Playing " + playlist[selection].filename + " ...");
playlist[selection].Play();
while (videoPlaying) Thread.Sleep(500);
playlist.RemoveAt(selection);
if (playlist.Count == 0) {
if (!repeatList) break;
BuildPlaylist();
}
}

它是有效的,但我希望我真的能以某种方式利用hasPlayed bool,这样添加它就不会毫无意义了,哈哈。我想既然它有效,那也没关系,但我只是好奇它是否可以。我也不确定制作这个过程的最佳方式"休息";而媒体播放器正在做它的事情;暂时睡觉是正确的做法吗?

最简单的方法可能是使用Random和LINQWhere只选择那些你还没有玩过的游戏:

// Select all where played == false
var notPlayed = playList.Where(x => !x.played).ToList();
// Create random Index, ensuring it is no larger than the count of unplayed songs
// Also, try not to create a new instance of random every time
var randomIndex = new Random().Next(notPlayed.Count);
// Play song
notPlayed[randomIndex].Play();

注意:尽量不要在循环中创建Random的实例,而是尝试创建一次,然后重新使用


以下是一些通常可以改进代码的指针,不一定与您的问题有关:

  1. 尝试使用内置的Framework,比如FileInfo类,它已经具有fileNamefilePath的属性(分别为NameDirectory(DirectoryName((。最好将它包装起来,并使用类似Path.GetExtension的东西来返回文件扩展名
  2. 试着遵守C#/。NET命名和样式约定(尤其是类型成员的名称((您可以查看NET Core源代码,了解MS是如何做到这一点的(

最新更新