use core::hash::Hash;
use std::collections::HashMap;
use std::iter::FusedIterator;
use crate::graph::Graph;
use crate::node::NodeId;
pub struct RankedNodes<'a, T: Eq + Hash + Clone> {
pub(crate) graph: &'a Graph<T>,
pub(crate) scores: Vec<f32>,
}
pub struct UnsortedRankedNodesIter<'a, T: Eq + Hash + Clone> {
inner: &'a RankedNodes<'a, T>,
index: usize,
}
pub struct SortedRankedNodesIter<'a, T: Eq + Hash + Clone> {
inner: &'a RankedNodes<'a, T>,
sorted_node_ids: Vec<(NodeId, f32)>,
index: usize,
}
impl<'a, T: Eq + Hash + Clone> RankedNodes<'a, T> {
pub fn hash_map(&self) -> HashMap<T, f32> {
self.unsorted_iter()
.map(|(data, score)| (data.clone(), score))
.collect()
}
pub fn unsorted_iter(&'a self) -> UnsortedRankedNodesIter<'a, T> {
UnsortedRankedNodesIter {
inner: self,
index: 0,
}
}
pub fn sorted_iter(&'a self) -> SortedRankedNodesIter<'a, T> {
let mut sorted_list: Vec<(NodeId, f32)> = self
.scores
.iter()
.enumerate()
.filter(|(_, score)| !score.is_nan())
.map(|(n, score)| (NodeId(n), *score))
.collect();
sorted_list.sort_by(|(_, a), (_, b)| b.partial_cmp(a).unwrap());
SortedRankedNodesIter {
inner: self,
sorted_node_ids: sorted_list,
index: 0,
}
}
pub fn get_score_for(&self, data: &T) -> Option<f32> {
let node = self.graph.nodes.get2(data)?;
self.scores.get(node.id.0).copied()
}
pub fn len(&self) -> usize {
self.scores.len()
}
pub fn is_empty(&self) -> bool {
self.scores.is_empty()
}
}
impl<'a, T: Eq + Hash + Clone> Iterator for UnsortedRankedNodesIter<'a, T> {
type Item = (&'a T, f32);
fn next(&mut self) -> Option<Self::Item> {
self.inner.scores.get(self.index).map(|score| {
let data = &self
.inner
.graph
.nodes
.get1(&NodeId(self.index))
.unwrap()
.data;
self.index += 1;
(data, *score)
})
}
}
impl<T: Eq + Hash + Clone> FusedIterator for UnsortedRankedNodesIter<'_, T> {}
impl<'a, T: Eq + Hash + Clone> Iterator for SortedRankedNodesIter<'a, T> {
type Item = (&'a T, f32);
fn next(&mut self) -> Option<Self::Item> {
self.sorted_node_ids
.get(self.index)
.map(|(node_id, score)| {
let data = &self.inner.graph.nodes.get1(node_id).unwrap().data;
self.index += 1;
(data, *score)
})
}
}
impl<T: Eq + Hash + Clone> FusedIterator for SortedRankedNodesIter<'_, T> {}