假设我想查看迭代器的第五个项目,但我想保留所有项目。最好的方法是什么?有模块吗?我可能可以将一个函数组合在一起来创建一个新的迭代器,但我想知道它是否已经完成了?
我有一个简单的排列结构:
struct Permutation
{
vector<string> items; // ["val_0", "val_1", "val_2", "val_3", "val_4"]
vector<short> permutationValue; // Let's say value is [4, 2, 0, 1, 3]
}
Run Code Online (Sandbox Code Playgroud)
我希望能够在范围循环中使用它,就像那样
for(string item: permutation){
{
cout << item << endl;
}
Run Code Online (Sandbox Code Playgroud)
最终预期产量应为:
val_4
val_2
val_0
val_1
val_3
Run Code Online (Sandbox Code Playgroud)
我应该在Permutation课堂上实施哪些方法来实现它?
我需要学习如何使用enable_if.为此,我需要使用enable_if重新实现distance函数.我试过这个:
#include <iostream>
#include <vector>
#include <list>
#include <utility>
#include <type_traits>
template<class In>
typename std::enable_if<!std::is_random_acces_iterator<In>::value, std::iterator_traits<In>::difference_type>::type my_distance(In begin, In end, std::input_iterator_tag dummy){
typename std::iterator_traits<In>::difference_type n = 0;
while(begin!=end){
++begin; ++n;
}
std::cout << "STEPPING" << std::endl;
return n;
}
template<class Ran>
typename std::enable_if<std::is_random_acces_iterator<Ran>::value, std::iterator_traits<In>::difference_type>::type my_distance(Ran begin, Ran end, std::random_access_iterator_tag dummy){
std::cout << "RANDOM" << std::endl;
return end - begin;
}
template <class I> inline
typename std::iterator_traits<I>::difference_type my_distance_wrapper(I begin, I end){
typedef typename std::iterator_traits<I>::iterator_category cat;
return my_distance(begin, end, cat());
}
int …Run Code Online (Sandbox Code Playgroud) 有没有办法在c ++中迭代优先级队列?我的理解是它们或多或少是不可变的,容器的唯一操作是顶层元素.我希望能够打印出优先级队列的内容,但不确定如何解决问题.
我正在编写一个迭代映射中的条目的函数。我希望能够干净地处理迭代时从地图中添加或删除的项目,就像for k, v := range myMap { //...所做的那样,但我每次迭代只处理一个键/值对,所以我不能使用范围。我想要这样的东西:
func processItem(i iterator) bool {
k, v, ok := i.next()
if(!ok) {
return false
}
process(v)
return true
}
var m = make(map[string]widget)
// ...
i := makeIterator(m)
for processItem(i) {
// code which might add/remove item from m here
}
Run Code Online (Sandbox Code Playgroud)
我知道 range 使用 ' hiter' 结构体和关联函数(如 中定义src/runtime/hashmap.go)来执行迭代。有没有什么方法可以访问这个迭代器作为一个具体化的(一流的)Go 对象?
是否有另一种迭代映射的策略可以很好地处理插入/删除,但提供一流的迭代器对象?
额外问题:是否有另一种迭代映射的策略,该策略还可以处理映射和迭代器被序列化到磁盘然后恢复的情况,迭代从停止的地方继续?(显然内置迭代range器不具备这个能力!)
在 PHP 7.1 中,有一个新的可迭代伪类型,它抽象数组和Traversable对象。
假设在我的代码中我有一个如下所示的类:
class Foo
{
private $iterable;
public function __construct(iterable $iterable)
{
$this->iterable = $iterable;
}
public function firstMethod()
{
foreach ($this->iterable as $item) {...}
}
public function secondMethod()
{
foreach ($this->iterable as $item) {...}
}
}
Run Code Online (Sandbox Code Playgroud)
$iterable这在is 数组或 an时工作得很好Iterator,除非$iterable是 a Generator。事实上,在这种情况下,调用firstMethod()thensecondMethod()将产生以下结果Exception: Cannot traverse an already closed generator。
有办法避免这个问题吗?
为什么生成器同时是可迭代器和迭代器是有用/必要的?
我认为可迭代和迭代器是完全不同的,例如集合是可迭代的,这意味着我可以在它上面请求一个迭代器,每次这样做我都会得到一个新的迭代器,它允许我单步遍历整个集合一次。
生成器看起来最像一个迭代器,即一旦你无法用它做任何事情,那么一旦你单步遍历它的元素,但除了实现next()它之外,还实现了 iterable 的 get-iterator 逻辑,但仅此逻辑返回发电机本身:
$ node
> const genFn = function* () { yield *[1, 2, 3]; }
> const gen = genFn();
> gen.next();
{ value: 1, done: false }
> gen == gen[Symbol.iterator]();
true
> for (const val of gen) console.log(val);
2
3
Run Code Online (Sandbox Code Playgroud)
为什么生成器除了是迭代器之外还必须是可迭代的?
我有一个迭代器,我想用一个很好的方法折叠它(比如说Iterator::sum):
let it = ...;
let sum = it.sum::<u64>();
Run Code Online (Sandbox Code Playgroud)
然后我注意到我还需要知道迭代器中元素的数量。我可以编写一个for循环并手动进行计数和求和,但这并不好,因为我必须更改可能很长的迭代器适配器链以及所有这些。此外,在我的真实代码中,我没有使用sum,而是使用更复杂的“折叠方法”,我不想复制该逻辑。
我有一个想法(ab)使用Iterator::inspect:
let it = ...;
let mut count = 0;
let sum = it.inspect(|_| count += 1).sum::<u64>();
Run Code Online (Sandbox Code Playgroud)
这是可行的,但它是巧合还是这种行为有保证?的文档inspect提到每个元素都会调用闭包,但也指出它主要用作调试工具。我不确定在生产代码中以这种方式使用它是否是一个好主意。
在 Rust 中,如何在for样式循环中执行可变大小的步骤?我可以使用此构造执行固定大小的步骤:
for i in (0..vals.len()).step_by(4)
{
println!("{}: {}", i, vals[i]);
}
Run Code Online (Sandbox Code Playgroud)
或者更合适的:
for (i,val) in vals.iter().enumerate().step_by(4)
{
println!("{}: {}", i, val);
}
Run Code Online (Sandbox Code Playgroud)
但我真正想做的是:
for i in 0..vals.len()
{
println!("{}: {}", i, vals[i]);
if vals[i] == 1 { i += 2; }
else if vals[i] == 2 { i += 4; }
}
Run Code Online (Sandbox Code Playgroud)
但当然,修改i不会影响循环迭代器。
由于主要具有 C 语言背景,现代语言对迭代器的依赖常常让人感觉像是戴着手套进行编程。通常谷歌会来救援,但我还没有找到任何解决方案来解决这个看似相当简单的问题。
我想出的最好的是
let mut i:usize = 0;
while i < vals.len()
{
println!("{}: {}", i, vals[i]);
if vals[i] == …Run Code Online (Sandbox Code Playgroud) iterator ×10
c++ ×4
c++11 ×2
generator ×2
iterable ×2
rust ×2
dictionary ×1
enable-if ×1
for-loop ×1
go ×1
javascript ×1
permutation ×1
php ×1
pointers ×1
python ×1
python-2.7 ×1
side-effects ×1
vector ×1