Beta

Normalizing State Shape #1

Description:

Normalizing State Shape Part 1

In web application development, managing state is crucial, especially when dealing with complex data structures. In this kata, you'll be tasked with normalizing the state of a blog application, specifically focusing on blog posts, comments, and users.

The input data represents a collection of blog posts with associated authors and comments. Your goal is to transform this data into a normalized state object, following the principles of database design.

To achieve this, you need to create a function called normalizeState(blogPosts), where blogPosts is an array of objects representing the blog posts.

Input

The input data blogPosts looks like this:

[
  {
    id: String,
    author: {
      username: String,
      name: String,
    },
    body: String,
    comments: [
      {
        id: String,
        author: {
          username: String,
          name: String,
        },
        comment: String,
      },
      // Repeat for more comments
    ],
  },
  // Repeat for more blog posts
]
  • The blogPosts array will always be provided as a valid array of objects representing blog posts.

  • Each blog post object will have the properties id (string), author (object), body (string), and comments (array).

  • The author property in each blog post object will have the properties username (string) and name (string).

  • The comments property in each blog post object will be an array of objects representing comments.

  • The comments array can be an empty array.

  • Each comment object will have the properties id (string), author (object), and comment (string).

  • The author property in each comment object will have the properties username (string) and name (string).

  • The username property in the author objects will be unique across the entire blogPosts array.

  • The id property in the blog post objects and the comment objects will be unique across the entire blogPosts array.

Output

The function should return a normalized state object according to the following schema:

{
  entities: {
    authors: {
      byId: {
        [username: String]: {
          username: String,
          name: String,
        },
      },
      allIds: [String],
    },
    posts: {
      byId: {
        [postId: String]: {
          id: String,
          author: String,
          body: String,
          comments: [String],
        },
      },
      allIds: [String],
    },
    comments: {
      byId: {
        [commentId: String]: {
          id: String,
          author: String,
          comment: String,
        },
      },
      allIds: [String],
    },
    authorPosts: {
      byId: {
        [username: String]: [String],
      },
      allIds: [String],
    },
  },
}
  • The authors object represents all authors (posts and comments).

  • Each blog post should be represented as an object in the posts object, using the post's id as the key. Each post object should have the properties id, author, body, and comments.

  • The author property in the post object should be a string representing the author's username.

  • The comments property in the post object should be an array of comment IDs associated with that post.

  • Each comment should be represented as an object in the comments object, using the comment's id as the key. Each comment object should have the properties id, author, and comment.

  • The author property in the comment object should be a string representing the author's username.

  • The authorPosts object should represent the relationship between authors and posts. The authorPosts object has two properties:

    • byId: An object where each key is an author's username and the corresponding value is an array of post IDs authored by that user.

    • allIds: An array containing all the usernames of authors.

  • The allIds arrays in each object should contain the IDs of the respective entities in the same order as they appear.

  • The byId objects can be ordered how you like. The ordering doesn't matter.

Example

Input:

const blogPosts = [
  {
    id: "post1",
    author: { username: "user1", name: "User 1" },
    body: "......",
    comments: [
      {
        id: "comment1",
        author: { username: "user2", name: "User 2" },
        comment: ".....",
      },
    ],
  },
  {
    id: "post2",
    author: { username: "user2", name: "User 2" },
    body: "......",
    comments: [],
  },
  {
    id: "post3",
    author: { username: "user3", name: "User 3" },
    body: "......",
    comments: [
      {
        id: "comment2",
        author: { username: "user1", name: "User 1" },
        comment: ".....",
      },
      {
        id: "comment3",
        author: { username: "user3", name: "User 3" },
        comment: ".....",
      },
    ],
  },
]

Output:

{
  entities: {
    authors: {
      byId: {
        user1: { username: "user1", name: "User 1" },
        user2: { username: "user2", name: "User 2" },
        user3: { username: "user3", name: "User 3" },
      },
      allIds: ["user1", "user2", "user3"],
    },
    posts: {
      byId: {
        post1: {
          id: "post1",
          author: "user1",
          body: "......",
          comments: ["comment1"],
        },
        post2: {
          id: "post2",
          author: "user2",
          body: "......",
          comments: [],
        },
        post3: {
          id: "post3",
          author: "user3",
          body: "......",
          comments: ["comment2", "comment3"],
        },
      },
      allIds: ["post1", "post2", "post3"],
    },
    comments: {
      byId: {
        comment1: {
          id: "comment1",
          author: "user2",
          comment: ".....",
        },
        comment2: {
          id: "comment2",
          author: "user1",
          comment: ".....",
        },
        comment3: {
          id: "comment3",
          author: "user3",
          comment: ".....",
        },
      },
      allIds: ["comment1", "comment2", "comment3"],
    },
    authorPosts: {
      byId: {
        user1: ["post1"],
        user2: ["post2"],
        user3: ["post3"],
      },
      allIds: ["user1", "user2", "user3"],
    },
  },
}

By organizing the state in this normalized structure, we can easily access and update specific entities and establish relationships between them. It provides efficient data retrieval and avoids data duplication, resulting in a more manageable and scalable state management solution.

In Part 2 (coming soon) we will be looking at CRUD operations on the normalized state.

Data Structures

Similar Kata:

More By Author:

Check out these other kata created by PrVille

Stats:

CreatedJun 9, 2023
PublishedJun 9, 2023
Warriors Trained85
Total Skips42
Total Code Submissions150
Total Times Completed13
JavaScript Completions13
Total Stars2
% of votes with a positive feedback rating83% of 9
Total "Very Satisfied" Votes7
Total "Somewhat Satisfied" Votes1
Total "Not Satisfied" Votes1
Total Rank Assessments9
Average Assessed Rank
5 kyu
Highest Assessed Rank
4 kyu
Lowest Assessed Rank
7 kyu
Ad
Contributors
  • PrVille Avatar
Ad