Skip to content

Feature Request: Add into_nodes_edges to StableGraph mirroring Graph #840

@BloodStainedCrow

Description

@BloodStainedCrow

Hello!

I recently (while trying to merge two StableGraphs) wanted to transform a StableGraph into an iterator (or a vec) of its NodeType. Unless I fully missed it, this is not possible with the current Api, unless one converts the StableGraph into a normal Graph first, which invalidates all NodeIndex and EdgeIndex.

Since anyone using a StableGraph is storing the indices somewhere (why else would they be using a StableGraph), this is just not an option.
My first solution included cloneing every Node, but that is not an option for everyone (and doubled the peak memory consumption of my program).

I then resorted to just forking petgraph and adding a simple implementation:

pub fn into_nodes_edges(self) -> (impl Iterator<Item = (NodeIndex<Ix>, N)>, impl Iterator<Item = (EdgeIndex<Ix>, NodeIndex<Ix>, NodeIndex<Ix>, E)>) {
    let (inner_nodes, inner_edges) = self.g.into_nodes_edges();

    (
        inner_nodes.into_iter().enumerate().filter_map(|(i, node)| node.weight.map(|node| (i, node))).map(|(index, node)| (NodeIndex::new(index), node)), 
        inner_edges.into_iter().enumerate().filter(|(_, edge)| edge.weight.is_some()).map(|(index, edge)| (EdgeIndex::new(index), edge.source(), edge.target(), edge.weight.unwrap()))
    )
}

This kind of API gives the user all the information that is stable and visible as a consumer of StableGraph, without exposing implementation details AFAIK.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions