标签: iterator

迭代/更新 HashMap

我知道有多种方法可以迭代哈希图,但是在进行过程中修改哈希图的好方法是什么(除了创建一个新的哈希图并删除旧的哈希图之外)

我想要类似的东西

for (Map.Entry<String, Integer> entry : wordcounts.entrySet()) {
    String key = entry.getKey();
    Integer value = entry.getValue();
    if(blacklist.contains(key))
        //remove key/value for that key from wordcounts
    if(mappings.contains(key))
     //change key in wordcounts from one string to another based on the key's value in a <string,string> map (mappings)
}
Run Code Online (Sandbox Code Playgroud)

我在浏览地图时可以修改地图吗?我必须使用迭代器吗?

java dictionary iterator hashmap hashset

6
推荐指数
1
解决办法
5893
查看次数

如何在多个排序列表上创建迭代器?

好的,所以这是我得到的一个面试问题,当时只进行了平庸的讨论.我想知道最佳解决方案是什么以及如何最好地实施.

您将得到多个分类列表,构建的东西,使我们能够遍历所有这些从最小的名单最大的元素.

例:

{ -2, 5, 10}
{ 2, 9, 11}
{ -5, 9}


-> -5, -2, 2, 5, 9, 9, 10, 11
Run Code Online (Sandbox Code Playgroud)

更新:

在SO聊天#c-questions-and-answers和@Nican的帮助下,我得到了这艘船以某种方式飞行.我已经发布了我的工作代码作为答案,以便允许其他解决方案.

我在下面发布的答案仍然很混乱,特别是我没有正确实现==和!=.我仍然需要帮助.

这个问题的理由

在线查找干净且简约的自定义迭代器实现并不常见.我相信这个问题可以作为其他人加强对迭代器和最佳实践的理解的良好起点.

c++ iterator stl

6
推荐指数
1
解决办法
122
查看次数

为什么 TypeScript 的 IterableIterator&lt;&gt; 和 Generator&lt;&gt; 泛型略有不同?

在 TypeScript (3.6.3) Generator<>中几乎与IterableIterator<>相同。当Generator<>扩展Iterator<> 时,它默认第三个泛型参数(TNext)unknownIterator<>本身默认TNextundefined。所以GeneratorIterator(以及IterableIterator)并没有像他们应该的那样排列。

let gen2:IterableIterator<string>;

function* gen1():Generator<string> {
    yield* gen2;
}
Run Code Online (Sandbox Code Playgroud)

yield* 行是一个错误:“无法将迭代委托给 value,因为其迭代器的 'next' 方法期望类型为 'undefined',但包含的生成器将始终发送 'unknown'.ts(2766)”。

我错过了什么吗?这有充分的理由吗?

iterator generator typescript

6
推荐指数
1
解决办法
921
查看次数

std::vector::iterator 是否可以合法地成为指针

我已经听说std::vector<T>::iterator可以简单地T*代替迭代器类。

但这真的合法吗?

指针算术仅适用于数组std::vector不创建数组对象 ( T[]) 而是创建连续对象(通过放置 new)。

此外,我认为std::launder甚至需要(C++17)来访问单个元素(正如我们可以在 的static_vector示例注释中阅读的那样std::aligned_storage)。

我认为这大致相当于遵循我认为是未定义的行为。

template <typename T, std::size_t N, typename F>
void test_array(F func)
    typename std::aligned_storage<sizeof (T) * N, alignof (T)>::type data;
    char* buffer = &data;
    for (std::size_t i = 0; i != N; ++i) {
        new (buffer + i * sizeof(T)) T;
    }
    T* array = reinterpret_cast<T*>(buffer);
    for (std::size_t i = 0; i != N; …
Run Code Online (Sandbox Code Playgroud)

c++ pointers iterator stdvector language-lawyer

6
推荐指数
1
解决办法
120
查看次数

Rust 从迭代器中收集哈希图

我们有一个 HashMap,我们对其进行迭代和映射以替换值,但是遇到了一个问题,将其收集回具有不同值类型的新 HashMap。

value of type `std::collections::HashMap<std::string::String, std::string::String>`
cannot be built from `std::iter::Iterator<Item=(&std::string::String, std::string::String)>`
Run Code Online (Sandbox Code Playgroud)

我们所做的基本上归结为:

let old: HashMap<String, Value> = some_origin();
let new: HashMap<String, String> = old.iter().map(|(key, value)| {
  return (key, some_conversion(value));
}).collect();
Run Code Online (Sandbox Code Playgroud)

如果对两个迭代器进行压缩,例如在这种情况下压缩键,并且映射仅返回转换后的值,则也会返回相同的迭代器类型(并且不可收集)。

new = old.keys().into_iter().zip(old.iter().map(|(key, value)| some_conversion(value)).collect();
Run Code Online (Sandbox Code Playgroud)

iterator tuples hashmap rust

6
推荐指数
1
解决办法
2005
查看次数

如何打印通用 std::list 迭代器?

我希望能够std::list通过打印其值来打印任何迭代器。我的初始代码如下所示:

template<typename T>
std::ostream& operator<<(std::ostream& os, const typename std::list<T>::const_iterator& x)
{
   return os << "&" << *x;
}

Run Code Online (Sandbox Code Playgroud)

哪个不起作用,因为编译器无法确定参数T。然后我尝试使它在迭代器类型本身上通用,并iterator_traits用于将其限制为迭代器。

template<
    typename It,
    typename = typename std::iterator_traits<It>::value_type
>
std::ostream &operator<<(std::ostream &os, const It &x)
{
    return os << "&" << *x;
}
Run Code Online (Sandbox Code Playgroud)

但是,当然,我得到了两个相互冲突的实现std::ostream << *const char,因为指针也是迭代器。如何将实现限制为std::list迭代器,以免发生冲突?

c++ templates iterator c++-standard-library c++17

6
推荐指数
2
解决办法
243
查看次数

为什么我不能从迭代器构造一个 std::span ?

考虑一个大内存容器。在这个简单的例子中std::vector<int>

std::vector v = { 0, 1, 2, 3, 4, 5 };
Run Code Online (Sandbox Code Playgroud)

std::span允许我创建一个轻量级的内存视图。现在我想简单地打印跨度:

template<typename T>
void print(std::span<T> span) {
    std::cout << '[';
    if (span.size())
        std::copy(span.begin(), span.end() - 1, std::ostream_iterator<int>(std::cout, ", "));

    std::cout << span.back() << "]\n";
}

int main() {
    std::vector v = { 0, 1, 2, 3, 4, 5 };

    print(std::span{ v });
}

Run Code Online (Sandbox Code Playgroud)

输出:

[0, 1, 2, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)

现在我想制作子集(这是std::span实际作为视图变得有用的地方)。我可以用迭代器来指定我的范围,并调用此构造函数(3)std::span

template< class It, class End >
explicit(extent != std::dynamic_extent) …
Run Code Online (Sandbox Code Playgroud)

c++ iterator c++20 std-span

6
推荐指数
1
解决办法
523
查看次数

为什么以下自定义迭代器实现不能很好地与 `std::all_of` 配合使用?

我正在研究一些需要包装另一个迭代器的迭代器类型。出于某种原因,自定义迭代器没有很好地定义。例如,它在与 一起使用时不会编译std::all_of,抱怨对 的函数调用不匹配std::iterator_category

/opt/.../stl_algo.h:108:32: error: no matching function for call to '__iterator_category(Iterator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >&)'
108 |        std::__iterator_category(__first));
Run Code Online (Sandbox Code Playgroud)

自定义迭代器公开了一个公共iterator_category类型,所以我不确定这里有什么问题。为了演示这个问题,自定义迭代器简单地包装了一些其他的迭代器类型:

#include <functional>
#include <iterator>
#include <vector>

template<typename It>
struct Iterator
{
  using difference_type = typename std::iterator_traits<It>::difference_type;
  using value_type = typename std::iterator_traits<It>::value_type;
  using pointer = value_type*;
  using reference_type = value_type&;
  using iterator_category = std::input_iterator_tag;

  Iterator(It it) : it_{it} {}

  friend bool operator==(const Iterator& x, const Iterator& y) { return x.it_ == y.it_; }
  friend bool operator!=(const …
Run Code Online (Sandbox Code Playgroud)

c++ iterator

6
推荐指数
1
解决办法
59
查看次数

如何模拟 Rust 中的可组合随机过程?

我正在编写一系列马尔可夫链蒙特卡罗 (MCMC)算法,通过将此处在 C++ 中实现的 MCMC 算法转换为 Rust 来用作程序归纳系统的推理方法。

MCMC 的粗略动态是我们有一些过程可以在对象空间周围随机移动并生成它发现的对象流。随机性是必不可少的。此外,此流永远不会终止(尽管您可以停止从流中获取对象)。更复杂的 MCMC 形式可以定义为这个基本过程的组合。

我的问题如何惯用地翻译这些算法?更具体地说,我如何从 rustacean 的角度考虑这个问题?为工作带来哪些正确的工具/技术?

这是我考虑过的:

  1. 直接翻译似乎很尴尬,因为 C++ 代码大量使用回调,鉴于我对 Rust 的了解有限,这感觉很尴尬。这似乎更符合我读过的其他 Rust 代码,只是让用户可以懒惰地使用他们认为合适的样本流。

  2. 然后我认为迭代器可能有意义,但是:

  • 我采样的对象是表示微型 DSL 的复杂数据结构。如果用户认为它是一个有用的样本,那么最好提供一个可以克隆的参考。我的理解是,鉴于 rust 的内存模型,这是迭代器的一个已知限制。
  • 这些算法都需要一个随机源(即&mut Rwhere R: Rng),并访问一个简单的控制结构来跟踪各种统计数据。将这些直接烘焙到任何结构实现中Iterator意味着我无法以共享控制结构或随机源的方式组合算法,对吗?
  1. 生成器/协程似乎解决了这些问题,但似乎是一个相对边缘/生锈的新领域。我开始怀疑我是否让事情变得比他们需要的更难。

  2. 我目前为每个算法提供了一个类似于以下函数的结构,其中H是假设,C是控制结构:

    impl<C, H> MCMCChain<C, H> {
        // ...
        pub fn next_sample<R: Rng>(&mut self, control: &mut C, rng: &mut R) -> Option<Self>
        // ...
    }
    
    Run Code Online (Sandbox Code Playgroud)

    理想情况下,next_sample会回来Option<&H>,但这就是我现在正在做的事情。

random algorithm iterator coroutine rust

6
推荐指数
0
解决办法
105
查看次数

从 C++17 中的迭代器范围复制分配给元组

我一直希望使用新的 C++17 功能,如折叠表达式,并std::apply()简化我使用的一些 C++11 代码,这些代码使用诸如std::index_sequence和 之类的工具std::initializer_list对元组进行某些操作。特别是一项任务给我带来了一些麻烦:将一系列值(例如从boost::tokenizer对象)复制到元组。我有一个工作解决方案,它调用std::apply()要为其分配值的元组,但仍必须在std::initializer_list内部使用(为简单起见,我用一个简单的向量替换了 boost 标记器迭代器:

#include <iostream>
#include <vector>
#include <tuple>

template<typename Tuple, typename Iterator>
size_t copy_range_to_tuple(Tuple& tup, Iterator begin, Iterator end) {
    size_t count = 0;
    auto copy = [&begin,&end,&count] (auto& value) -> bool {
        if (begin != end) {
            value = *(begin++);
            ++count;
            return true;
        } else {
            return false;
        }
    };
    std::apply([&copy](auto&... values) {
        std::initializer_list<bool>{copy(values)...};
    }, tup);
    return count;
}

int main(int,char**) …
Run Code Online (Sandbox Code Playgroud)

c++ iterator tuples fold-expression c++17

6
推荐指数
1
解决办法
65
查看次数