Advertisement
Guest User

Untitled

a guest
Sep 22nd, 2023
315
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 2.27 KB | None | 0 0
  1. use std::cmp::Reverse;
  2. use std::collections::BinaryHeap;
  3.  
  4. use rustc_hash::FxHashMap;
  5. use serde::{Deserialize, Serialize};
  6. use serde_json::from_str;
  7.  
  8. #[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)]
  9. struct Post {
  10.     _id: String,
  11.     title: String,
  12.     // #[serde(skip_serializing)]
  13.     tags: Vec<String>,
  14. }
  15.  
  16. #[derive(Debug, Serialize)]
  17. struct RelatedPosts<'a> {
  18.    _id: &'a str,
  19.     tags: &'a [String],
  20.    related: Vec<&'a Post>,
  21. }
  22.  
  23. fn main() {
  24.     let json_str = std::fs::read_to_string("../posts.json").unwrap();
  25.     let posts: Vec<Post> = from_str(&json_str).unwrap();
  26.  
  27.     let mut posts_by_tag = FxHashMap::default();
  28.     posts
  29.         .iter()
  30.         .enumerate()
  31.         .flat_map(|(idx, post)| std::iter::repeat(idx).zip(post.tags.iter().map(|x| x.as_str())))
  32.         .for_each(|(idx, tag)| {
  33.             posts_by_tag.entry(tag).or_insert(vec![]).push(idx);
  34.         });
  35.  
  36.     let mut related_posts = Vec::with_capacity(posts.len());
  37.     for (idx, post) in posts.iter().enumerate() {
  38.         let mut tagged_post_count = FxHashMap::default();
  39.  
  40.         post.tags
  41.             .iter()
  42.             .map(|tag| posts_by_tag.get(tag.as_str()))
  43.             .flatten()
  44.             .flat_map(|x| x.iter())
  45.             .filter(|&&tagged_post| tagged_post != idx)
  46.             .for_each(|&tagged_post| {
  47.                 *tagged_post_count.entry(tagged_post).or_insert(0) += 1;
  48.             });
  49.  
  50.         let mut top_five = BinaryHeap::new();
  51.         tagged_post_count.iter().for_each(|(&post, &count)| {
  52.             if top_five.len() < 5 {
  53.                 top_five.push((Reverse(count), post));
  54.             } else {
  55.                 let (Reverse(cnt), _) = top_five.peek().unwrap();
  56.                 if count > *cnt {
  57.                     top_five.pop();
  58.                     top_five.push((Reverse(count), post));
  59.                 }
  60.             }
  61.         });
  62.  
  63.         related_posts.push(RelatedPosts {
  64.             _id: &post._id,
  65.             tags: &post.tags,
  66.             related: top_five.into_iter().map(|(_, post)| &posts[post]).collect(),
  67.         });
  68.     }
  69.  
  70.     // Write the result to a JSON file.
  71.     let json_str = serde_json::to_string(&related_posts).unwrap();
  72.     std::fs::write("../related_posts_rust.json", json_str).unwrap();
  73. }
  74.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement