#node-tree #tree #builder #flat #root-node #flange

flange-flat-tree

一种可以通过在不改变旧节点的情况下附加新值来扩展的树

7个版本

0.2.2 2022年10月20日
0.2.1 2022年10月17日
0.1.3 2022年10月9日

#874数据结构

Download history 5/week @ 2024-03-13 15/week @ 2024-03-27 26/week @ 2024-04-03

68 每月下载量
svg-diff 中使用

MIT 许可证

44KB
748

flange-flat-tree

一个Rust实现,将节点存储在扁平数组(确切地说是Vec)中,并允许向节点添加更多数据。

示例

构建树。

树使用Builder构建。之后,树不能再更改。

use flange_flat_tree::{Builder, Tree, Subtree};

let mut b = Builder::new();
b.start_element("one"); // The root node
b.start_end_element("two"); // This will be a child of "one"
b.start_element("three"); // This will be a child of "one"
b.start_end_element("four"); // This will be a child of "three"
b.end_element(); // End "three"
b.end_element(); // End "one" (the root)

let tree = b.build();
assert_eq!(tree.root().value(), &"one");
assert_eq!(tree.root().child_values(), [&"two", &"three"]);

但您仍然可以通过使用索引在builder中更改树的元素

use flange_flat_tree::{Builder, Tree, Subtree};

struct Node {
    pub name: String,
    pub value: u32,
}

let mut b = Builder::new();
let root_id = b.start_element(Node { name: "one".to_string(), value: 1 }); // The root node
b.start_end_element(Node { name: "two".to_string(), value: 2 }); // This will be a child of "one"

// Change root afterwards
b.get_mut(root_id).unwrap().name = "root".to_string();
b.end_element(); // End "one" (the root)

let tree = b.build();
assert_eq!(tree.root().value().name, "root".to_string());

有关详细信息,请参阅builder

添加数据

在构建树之后,可以向树节点添加额外的数据。这意味着添加数据不会修改原始树或复制其数据。

“添加”可以有两种方式

使用“flange”添加

您可以使用tree.flange来添加。这将创建一个新的树,该树引用旧树并添加从传递给tree.flange的向量中添加的新数据。向量被消耗,因此它归新树所有。

Vec中的节点与原始树中具有相同索引的节点相关联。当您访问树时,您会得到一个包含值引用的元组

use flange_flat_tree::{Builder, Tree, Subtree};

let mut builder = Builder::with_capacity(2);
builder.start_element("one".to_string());
builder.start_end_element("two".to_string());
builder.end_element();
let tree = builder.build();

// flanged values
let values: Vec<u32> = (10..12).collect();

let tree_with_values = tree.flange(values);
assert_eq!(tree_with_values.root().value(), (&"one".to_string(), &10));

您也可以直接从原始树映射创建flange

use flange_flat_tree::{Builder, Tree, Subtree};

let mut builder = Builder::with_capacity(2);
builder.start_element("one".to_string());
builder.start_end_element("two".to_string());
builder.end_element();
let tree = builder.build();

let tree_with_values = tree.flange_map(
    |n| format!("{}-flanged", n)
);

assert_eq!(tree_with_values.root().value(), (&"one".to_string(), &"one-flanged".to_string()));

这也可以以“深度优先”的方式完成,在这种情况下,在创建节点之前就可以获得子节点

use flange_flat_tree::{Builder, Tree, Subtree};

let mut builder = Builder::with_capacity(2);
builder.start_element("one".to_string());
builder.start_end_element("two".to_string());
builder.end_element();
let tree = builder.build();

let tree_with_values = tree.depth_first_flange(
    |n, childs| format!("{} with {} children", n, childs.len())
);

assert_eq!(tree_with_values.root().value(), (&"one".to_string(), &"one with 1 children".to_string()));
assert_eq!(tree_with_values.root().children()[0].value(), (&"two".to_string(), &"two with 0 children".to_string()));

使用映射添加

如果您想通过命名属性访问树及其flange,您必须为它创建一个类型。该类型应引用它公开的值。然后您可以使用带有闭包的tree.map来使用tree.map。您还可以通过这种方式将现有树与外部数据相结合

use flange_flat_tree::{Builder, Tree, Subtree};

let mut builder = Builder::with_capacity(2);
builder.start_element("one");
builder.start_end_element("two");
builder.end_element();
let tree = builder.build();

struct FlangedNode<'a> {
    pub name: &'a str,
    pub value: u32, // we don't use a reference for u32, because copying the value itself is fine
}

// The data we are going to flange
let data: Vec<u32> = vec![1,2];

let tree_with_values = tree.map(
    |i,v| FlangedNode {
        name: v,
        value: data[i],
    }
);

assert_eq!(tree_with_values.root().value().name, "one");
assert_eq!(tree_with_values.root().value().value, 1);

安装

请参阅https://crates.io/crates/flange-flat-tree并添加

flange-flat-tree = "0.2.1"

当前版本:0.2.1

许可证:MIT

无运行时依赖项