Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::cmp::Reverse;
- use std::collections::BinaryHeap;
- use rustc_hash::FxHashMap;
- use serde::{Deserialize, Serialize};
- use serde_json::from_str;
- #[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)]
- struct Post {
- _id: String,
- title: String,
- // #[serde(skip_serializing)]
- tags: Vec<String>,
- }
- #[derive(Debug, Serialize)]
- struct RelatedPosts<'a> {
- _id: &'a str,
- tags: &'a [String],
- related: Vec<&'a Post>,
- }
- fn main() {
- let json_str = std::fs::read_to_string("../posts.json").unwrap();
- let posts: Vec<Post> = from_str(&json_str).unwrap();
- let mut posts_by_tag = FxHashMap::default();
- posts
- .iter()
- .enumerate()
- .flat_map(|(idx, post)| std::iter::repeat(idx).zip(post.tags.iter().map(|x| x.as_str())))
- .for_each(|(idx, tag)| {
- posts_by_tag.entry(tag).or_insert(vec![]).push(idx);
- });
- let mut related_posts = Vec::with_capacity(posts.len());
- for (idx, post) in posts.iter().enumerate() {
- let mut tagged_post_count = FxHashMap::default();
- post.tags
- .iter()
- .map(|tag| posts_by_tag.get(tag.as_str()))
- .flatten()
- .flat_map(|x| x.iter())
- .filter(|&&tagged_post| tagged_post != idx)
- .for_each(|&tagged_post| {
- *tagged_post_count.entry(tagged_post).or_insert(0) += 1;
- });
- let mut top_five = BinaryHeap::new();
- tagged_post_count.iter().for_each(|(&post, &count)| {
- if top_five.len() < 5 {
- top_five.push((Reverse(count), post));
- } else {
- let (Reverse(cnt), _) = top_five.peek().unwrap();
- if count > *cnt {
- top_five.pop();
- top_five.push((Reverse(count), post));
- }
- }
- });
- related_posts.push(RelatedPosts {
- _id: &post._id,
- tags: &post.tags,
- related: top_five.into_iter().map(|(_, post)| &posts[post]).collect(),
- });
- }
- // Write the result to a JSON file.
- let json_str = serde_json::to_string(&related_posts).unwrap();
- std::fs::write("../related_posts_rust.json", json_str).unwrap();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement