每个都有一个动态列表
本文关键字:动态 列表 有一个 | 更新日期: 2023-09-27 17:57:51
我有一个for each循环,它在数据库中运行,以检查已标记为要转换的文件。目前我有以下代码:
/* All files flagged for invidual conversion will be stored in here. */
ArrayList files = vc.getFilesForInvidualConversion();
foreach (FileInfoExtended file in files)
{
// As long as the status flag hasn't been changed it can continue.
if (abort == false)
{
if (vc.isFileInUse(file) == false)
{
// Converting the video file.
vc.convertVideoToFLV(file);
}
}
vc.getFilesForInvidualConversion();
}
在第一行中,你可以看到我用对象填充了一个ArrayList,它将用for each来遍历这些对象。但是,在列表中的每个文件之后,我都想检查是否有可能需要转换的新文件。当我再次填充ArrayList时,for each似乎没有注意到,它会继续使用从第一行代码中收到的原始文件。我宁愿它更新"文件"-ArrayList,这样它也可以转换新文件。
这可能吗?
编辑:您给出的答案都适用于此场景,但我想添加一些内容。循环过程中是否可以从列表中删除文件?为了让它不会改变这一点?
第2版:这就是我现在拥有的:
List<FileInfoExtended> files = vc.getFilesForInvidualConversion();
while (files.Count > 0)
{
if (abort == false)
{
if (vc.isFileInUse(files[0]))
{
vc.convertVideoToFLV(files[0]);
}
}
files = vc.getFilesForInvidualConversion();
}
它在这两种情况下都有效(当文件被添加到列表中时和当文件被从列表中删除时)。我不知道这是否是一个性能方面的好解决方案,但现在它适合我的需求。除非我忽略了一些问题?
任何评论都将不胜感激!谨致问候,Floris
我建议使用其他集合,而不是ArrayList
。例如CCD_ 2。然后这样写smth:
while (stack.Any())
{
var item = stack.Pop();
// convert item
}
// All items were converted
在任何时候,您都可以stack.Push()
新项目。
第页。S.:使用非通用ArrayList
有什么意义吗?
您可以使用标准的"for"循环。foreach循环要求集合在遍历过程中是不可变的。"for"循环没有此约束。但是,在这种情况下,获取"for"循环的结束条件约束可能很困难。
我会考虑保留一个已经处理的文件列表,这样当您第二次通过时,您就可以检查是否已经处理了特定的文件。
实现这一点的明智方法是处理批次:当每个批次完成时,获得另一个批次,直到达到空批次(这与@j0rd4n建议的方法相同)。以下是如何将这个逻辑封装在一个漂亮的foreach
循环中:首先,创建一个类来管理迭代:
namespace StackOverflow6128549
{
class FileInfoExtended
{
public int PropertyX { get; set; }
}
class IncrediblySmartIteration : IEnumerable<FileInfoExtended>
{
private List<FileInfoExtended> GetFilesToProcess()
{
throw new NotImplementedException();
}
#region IEnumerable<FileInfoExtended> Members
private IEnumerator<FileInfoExtended> InternalGetEnumerator()
{
List<FileInfoExtended> filesToProcess = null;
do
{
filesToProcess = GetFilesToProcess();
foreach (var fi in filesToProcess)
{
yield return fi;
}
}
while (filesToProcess.Count > 0);
}
public IEnumerator<FileInfoExtended> GetEnumerator()
{
return InternalGetEnumerator();
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return InternalGetEnumerator();
}
#endregion
}
}
然后,您将能够使用简单的foreach
:运行这种类型的对象
var container = new IncrediblySmartIteration();
foreach (var fi in container)
{
Console.WriteLine(fi.PropertyX);
}
请注意,在设计GetFilesToProcess()方法时,应该注意保证终止。请务必考虑在查找新文件时出现错误时会发生什么。
您可以使用递归将索引传递给递归函数,以便评估您在数组中的位置。
void ConvertRecursively(int index, typeForVC vc)
{
if(abort)
return;
ArrayList files = vc.getFilesForInvidualConversion();
if(index !< files.Count)
return;
else
{
if (vc.isFileInUse(files[index]) == false)
{
// Converting the video file.
vc.convertVideoToFLV(files[index]);
}
return ConvertRecursive(++index, vc);
}
}
打电话只需做:
ConvertRecursively(0, typeForVC vc);
更新:如果您需要处理数组大小也减小的情况,同样,最后一条流控制语句是不必要的,所以我去掉了它:
void ConvertRecursively(int index, int prevSize, typeForVC vc)
{
if(abort)
return;
ArrayList files = vc.getFilesForInvidualConversion();
int sizeDifferential = files.Count <= prevSize ? prevSize - files.Count : 0;
int adjustedIndex = index - sizeDifferential;
if(adjustedIndex !< files.Count)
return;
if (vc.isFileInUse(files[adjustedIndex]) == false)
{
// Converting the video file.
vc.convertVideoToFLV(files[adjustedIndex]);
}
return ConvertRecursive(++adjustedIndex, files.Count, vc);
}
打电话只需做:
ConvertRecursively(0, 0, typeForVC vc);
好的,现在我只是玩得很开心。希望它对你有用。我还没有测试过这个b.t.w.