仅当使用生锈的地图中不存在对象时,如何将新对象插入地图?
How to insert the new object to the map only if the object doesn't exist in the map using rust?
我正在将 C++ 代码传输到 Rust。
这是原始的 C++ 代码。
#include <map>
#include <string>
#include <cassert>
#include <iostream>
int main() {
std::map<std::string, int> m {
{ "A", 1 },
{ "B", 2 },
{ "D", 4 },
};
// *1
auto r = m.equal_range("C"); // *2
if (r.first == r.second) {
auto const& it = r.first;
assert(it->first == "D");
assert(it->second == 4);
// Let's say creating the object to insert is high cost
// so it should be created only if the element doesn't exist.
// Creating the object at *1 is not acceptable because if the element exists,
// then the created object isn't userd.
//
// `it` is hint iterator that point to insertion position.
// If the object to isnert has the same key as the argument of equal_range (*2)
// the time complexity is O(1).
m.emplace_hint(it, "C", 3);
}
for (auto const& kv : m) {
std::cout << kv.first << ":" << kv.second << std::endl;
}
}
可运行演示:https://wandbox.org/permlink/4eEZ2jY9kaOK9ru0
如果模式不存在则插入。
我想存档两个目标。
一个正在高效地插入对象。搜索对象需要 O(logN) 时间复杂度。我只想在地图中不存在该对象时插入新对象。如果从头开始插入新对象,则需要 O(logN) 额外成本来搜索插入位置。
原始 C++ 代码使用 it
作为插入新对象的提示。
另一个仅当映射中不存在具有相同键的对象时才创建新对象。因为在实际情况下创建对象需要很高的成本。 (我的示例代码用户 std::string 和 int 值。它只是一个示例。)
所以,我不想预先创建要在 *1 处插入的对象。
我阅读了 BTreeMap 文档。但是找不到路
https://doc.rust-lang.org/std/collections/struct.BTreeMap.html
有什么好的方法吗?
或者是否有任何非标准容器(地图)来支持我想做的操作?
您似乎想要条目 API?
在你的示例中,m.entry("C")
将 return 一个 Entry 枚举,其中包含条目是否存在的信息。然后,您可以显式分派或使用其中一种高级方法,例如BTreeMap::or_insert_with
它接受一个函数(从而创建要延迟插入的对象)
所以 Rust 版本应该是这样的:
let mut m = BTreeMap::new();
m.insert("A", 1);
m.insert("B", 2);
m.insert("D", 4);
m.entry("C").or_insert_with(|| {
3 // create expensive object here
});
for (k, v) in &m {
println!("{}:{}", k, v);
}
我正在将 C++ 代码传输到 Rust。 这是原始的 C++ 代码。
#include <map>
#include <string>
#include <cassert>
#include <iostream>
int main() {
std::map<std::string, int> m {
{ "A", 1 },
{ "B", 2 },
{ "D", 4 },
};
// *1
auto r = m.equal_range("C"); // *2
if (r.first == r.second) {
auto const& it = r.first;
assert(it->first == "D");
assert(it->second == 4);
// Let's say creating the object to insert is high cost
// so it should be created only if the element doesn't exist.
// Creating the object at *1 is not acceptable because if the element exists,
// then the created object isn't userd.
//
// `it` is hint iterator that point to insertion position.
// If the object to isnert has the same key as the argument of equal_range (*2)
// the time complexity is O(1).
m.emplace_hint(it, "C", 3);
}
for (auto const& kv : m) {
std::cout << kv.first << ":" << kv.second << std::endl;
}
}
可运行演示:https://wandbox.org/permlink/4eEZ2jY9kaOK9ru0
如果模式不存在则插入。
我想存档两个目标。
一个正在高效地插入对象。搜索对象需要 O(logN) 时间复杂度。我只想在地图中不存在该对象时插入新对象。如果从头开始插入新对象,则需要 O(logN) 额外成本来搜索插入位置。
原始 C++ 代码使用 it
作为插入新对象的提示。
另一个仅当映射中不存在具有相同键的对象时才创建新对象。因为在实际情况下创建对象需要很高的成本。 (我的示例代码用户 std::string 和 int 值。它只是一个示例。) 所以,我不想预先创建要在 *1 处插入的对象。
我阅读了 BTreeMap 文档。但是找不到路
https://doc.rust-lang.org/std/collections/struct.BTreeMap.html
有什么好的方法吗? 或者是否有任何非标准容器(地图)来支持我想做的操作?
您似乎想要条目 API?
在你的示例中,m.entry("C")
将 return 一个 Entry 枚举,其中包含条目是否存在的信息。然后,您可以显式分派或使用其中一种高级方法,例如BTreeMap::or_insert_with
它接受一个函数(从而创建要延迟插入的对象)
所以 Rust 版本应该是这样的:
let mut m = BTreeMap::new();
m.insert("A", 1);
m.insert("B", 2);
m.insert("D", 4);
m.entry("C").or_insert_with(|| {
3 // create expensive object here
});
for (k, v) in &m {
println!("{}:{}", k, v);
}