好吧,这里有一段很糟糕的代码:
public class Log : CachingProxyList<Event> {
public static Log FromFile(String fullPath) {
using (FileStream fs = new FileStream(fullPath, FileMode.Open, FileAccess.Read)) {
using (StreamReader sr = new StreamReader(fs)) {
return new Log(sr);
}
}
}
public Log(StreamReader stream)
: base(Parser.Parse(Parser.Tokenize(stream))) {
/* Here goes some "magic", the whole reason for this
* class to exist, but not really relevant to the issue */
}
}
Run Code Online (Sandbox Code Playgroud)
现在问题的一些背景:
CachingProxyList是一个IEnumerable<T>提供自定义"缓存"枚举器的实现:它接受一个IEnumerable<T>构造函数,最初通过它进行枚举,但是将每个项目保存在私有List<T>字段上,以便在继续进行实际解析之前进行进一步的迭代(而不是不时地解析;或者只是解析一个巨大的日志来查询它的一小部分).
请注意,实际上需要进行此优化,并且大部分已经在使用(如果我删除了using语句,除了泄漏的文件句柄外,一切都很顺利).
这两个 …
我想编写一个枚举,只是将一个Input.El推入迭代,然后返回剩余的iteratee.我把它称为prepend,因为它只是通过为它添加一个值来改变流.这是我的尝试:
object Enumeratees {
def prepend[T](toPrepend: T) = new Enumeratee[T, T] {
def applyOn[A](inner: Iteratee[T, A]): Iteratee[T, Iteratee[T, A]] = {
val prepended = Iteratee.flatten(inner.feed(Input.El(toPrepend)))
Done(prepended, Input.Empty)
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我现在通过它来称呼它
Enumerator(1,2,3,4) |>> (Enumeratees.prepend(0) &>> Iteratee.foreach[Int]{i=>println(i)})
Run Code Online (Sandbox Code Playgroud)
它只打印应该预先添加的0.枚举器中的其他值将被忽略.如果我也覆盖枚举的&>方法(转换方法),我可以使它工作:
def prepend[T](toPrepend: T) = new Enumeratee[T, T] {
def applyOn[A](inner: Iteratee[T, A]): Iteratee[T, Iteratee[T, A]] = {
val prepended = Iteratee.flatten(inner.feed(Input.El(toPrepend)))
Done(prepended, Input.Empty)
}
override def transform[A](inner: Iteratee[T,A]): Iteratee[T,A] =
Iteratee.flatten(inner.feed(Input.El(toPrepend)))
}
Run Code Online (Sandbox Code Playgroud)
但这不是一种非常干净的方式,因为applyOn方法仍然无效.我想我错误地认识了applyOn方法的含义.在我看来,它应该返回一个返回原始iteratee的iteratee,然后在原始iteratee上继续输入.
上面的转换方法应该解释一下,我想从我的枚举中得到什么样的行为.如何通过覆盖applyOn而不是transform来实现这种行为?
我试图在TEnumerator中公开构建私有静态数组.
Delphi本身允许直接枚举静态数组(见下文),所以我怀疑Delphi在后台为静态数组创建一个枚举器,我希望我能够在GetEnumerator方法中创建和公开相同的枚举器.
(我使用的是Delphi XE2).
program Project6;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
System.Generics.Collections;
type
TMyEnum = (meA, meB);
TMyClass = class
private
FItems: array[TMyEnum] of Integer;
protected
public
function GetEnumerator: TEnumerator<Integer>;
end;
{ TMyClass }
function TMyClass.GetEnumerator: TEnumerator<Integer>;
begin
// What is the simplies way of creating this enumerator?
end;
var
myObj: TMyClass;
i: Integer;
begin
myObj := TMyClass.Create;
try
// This works but only in the same unit
for i in myObj.FItems do
WriteLn(i);
for i in myObj do …Run Code Online (Sandbox Code Playgroud) 我正在使用Spring4D进行所有收藏.
现在有一种情况我必须知道枚举器的当前值是集合中的第一个(很容易)还是最后一个(很难).
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
Spring.Collections;
var
Enumerable: IEnumerable<Integer>;
Enumerator: IEnumerator<Integer>;
begin
Enumerable := TEnumerable.Query<Integer>(TArray<Integer>.Create(1, 2, 3, 4, 5)
) as IEnumerable<Integer>;
Enumerator := Enumerable.GetEnumerator;
while Enumerator.MoveNext do
begin
WriteLn('Value = ', Enumerator.Current);
WriteLn('First in collection? ', Enumerator.CurrentIsFirst);
WriteLn('Last in collection? ', Enumerator.CurrentIsLast);
end;
ReadLn;
end.
Run Code Online (Sandbox Code Playgroud)
CurrentIsFirst 可以使用本地布尔值实现,该布尔值在第一个值通过后重置.
但是,我不知道一种简单的实施方法CurrentIsLast.
它应该能够处理延迟集合,因为它们可能包含太多值以适应内存.
我该如何实现这样的CurrentIsLast功能?
在构建了一个BST<Tkey,TValue>由BSTNode<Tkey,TValue>节点组成的二叉搜索树之后,我试图为它实现IEnumerable接口.
这就是我构建的方式BSTNodeEnumrator<Tkey,TValue>:
public class BSTNodeEnumerator<TKey, TValue> : IEnumerator<BSTNode<TKey, TValue>> where TKey : IComparable<TKey>
{
private Stack<BSTNode<TKey, TValue>> _stack;
public BSTNodeEnumerator(BSTNode<TKey, TValue> root)
{
_stack = new Stack<BSTNode<TKey, TValue>>();
_current = null;
_root = root;
}
// ... rest of the implementation
}
Run Code Online (Sandbox Code Playgroud)
我传入root节点并且_current是枚举的结果.我也试图使用堆栈,因为我不像AVL BST那样跟踪父节点.
现在我希望枚举器以非递归的方式按顺序遍历树.这应该导致排序的枚举,因为bst的属性,这是伟大的,因为这正是我想要实现的.
用于在伪代码中遍历的非递归算法,如本维基百科文章中所述
iterativeInorder(node)
s ? empty stack
while (not s.isEmpty() or node ? null)
if (node ? null)
s.push(node)
node ? node.left
else
node ? …Run Code Online (Sandbox Code Playgroud) 我来自 Python 世界,正在尝试用 C# 创建一个“生成器”方法。我正在以特定缓冲区大小的块解析文件,并且只想一次读取并存储下一个块并在循环中生成它foreach。这是我到目前为止所拥有的(简化的概念证明):
class Page
{
public uint StartOffset { get; set; }
private uint currentOffset = 0;
public Page(MyClass c, uint pageNumber)
{
uint StartOffset = pageNumber * c.myPageSize;
if (StartOffset < c.myLength)
currentOffset = StartOffset;
else
throw new ArgumentOutOfRangeException("Page offset exceeds end of file");
while (currentOffset < c.myLength && currentOffset < (StartOffset + c.myPageSize))
// read data from page and populate members (not shown for MWE purposes)
. . .
}
}
class MyClass …Run Code Online (Sandbox Code Playgroud) 我对如何从Enumerator对象中获取值感兴趣.在下面的一段代码中,我期待第一次enum.next调用引发异常,因为enum在调用之后已经收到了所有值enum.to_a.
enum = Enumerator.new do |yielder|
yielder.yield 1
yielder.yield 2
yielder.yield 3
end
p enum.to_a # => [1, 2, 3]
puts enum.next # Expected StopIteration here
puts enum.next
puts enum.next
puts enum.next # => StopIteration exception raised
Run Code Online (Sandbox Code Playgroud)
调用next与迭代器方法之间的区别to_a是Enumerator什么?
许多语言都问过这个问题,但不是 javascript。
Ruby 有这样的方法Enumerable#each_cons:
puts (0..5).each_cons(2).to_a
# [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5]]
puts (0..5).each_cons(3).to_a
# [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
Run Code Online (Sandbox Code Playgroud)
我怎么能在 javascript 中有类似的方法Array呢?
在给定的代码中是否存在此错误的真正原因,或者只是在一般使用中可能会出错,其中跨交互器步骤需要引用(在这种情况下并非如此)?
IEnumerable<string> EnumerateStatic()
{
foreach (int i in dict.Values)
{
ref var p = ref props[i]; //< CS8176: Iterators cannot have by-reference locals
int next = p.next;
yield return p.name;
while (next >= 0)
{
p = ref props[next];
next = p.next;
yield return p.name;
}
}
}
struct Prop
{
public string name;
public int next;
// some more fields like Func<...> read, Action<..> write, int kind
}
Prop[] props;
Dictionary<string, int> dict;
Run Code Online (Sandbox Code Playgroud)
dict是名称索引映射,不区分大小写
Prop.next是 …
这可能是一个愚蠢的问题,所以请友善,哈哈。我正试图集中精力思考我刚刚遇到的事情。
第一的
我有一个可以使用以下内容枚举的哈希表:
$ht = [hashtable]@{"Key1"="Value1";"Key2"="Value2"}
$ht.GetEnumerator()
Name Value
---- -----
Key1 Value1
Key2 Value2
Run Code Online (Sandbox Code Playgroud)
如果我将其存储到一个变量中,则它仅在该变量的一次调用中存在。
$KeyPairs = $ht.GetEnumerator()
$KeyPairs
Name Value
---- -----
Key1 Value1
Key2 Value2
$KeyPairs
# Nothing is returned as if $KeyPairs lost its value
Run Code Online (Sandbox Code Playgroud)
有人可以帮助我理解为什么会这样吗?
第二
通常,对于集合,我有时想要针对单个项目进行测试(例如查看一个实例的属性),我可以使用 Select-Object 或通过索引:
$array = @("Value1","Value2")
$array | select -first 1
Value1
$array[0]
Value1
Run Code Online (Sandbox Code Playgroud)
哈希表枚举器似乎只支持 Select-Option,而不支持索引。
$ht = [hashtable]@{"Key1"="Value1";"Key2"="Value2"}
$ht.GetEnumerator() | Select -first 1
$ht.GetEnumerator() | Select -first 1
Name Value
---- -----
Key1 Value1
($ht.GetEnumerator() | measure).count
2 …Run Code Online (Sandbox Code Playgroud) enumerator ×10
c# ×4
arrays ×2
delphi ×2
ruby ×2
algorithm ×1
delphi-xe2 ×1
delphi-xe7 ×1
dispose ×1
enumeration ×1
equivalent ×1
foreach ×1
generator ×1
hashtable ×1
ienumerable ×1
iterate ×1
javascript ×1
powershell ×1
ref ×1
scala ×1
spring4d ×1
static-array ×1