如何标准化对象数组以提高性能

问题描述 投票:0回答:1

我正在尝试使用对象学习规范化概念。我对此有疑问

普通对象数组:

const state = {
users: [
    { id: 1, name: "Alice", posts: [{ id: 101, title: 'Post 1', comments: [{ id: 202, text: 'comment 2' }, { id: 201, text: 'comment 1' }] }] },
    { id: 2, name: "Bob", posts: [{ id: 102, title: 'Post 2', comments: [{ id: 202, text: 'comment 2' }] }] }
],
tags: [
    { id: 301, name: 'Tech', posts: [{ id: 101, title: 'Post 1' }, { id: 102, title: 'Post 2' }] },
     
]}

标准化结构

const state1 = {
users: {
    byIds: {
        1: { id: 1, name: "Alice", posts: [101] },
        2: { id: 2, name: "Bob", posts: [102] }
    },
    allIds: [1, 2]
},
posts: {
    byIds: {
        101: { id: 101, title: 'Post 1', comments: [201] },
        102: { id: 102, title: 'Post 2', comments: [202] }
    },
    allIds: [101, 102]
},
comments: {
    byIds: {
        201: { id: 201, text: 'comment 1' },
        202: { id: 202, text: 'comment 2' }
    },
    allIds: [201, 202]
},
tags: {
    byIds: {
        301: { id: 301, name: 'Tech', posts: [101, 102] },
        302: { id: 302, name: 'Travel', posts: [102] }
    },
    allIds: [301, 302]
}}

现在,在标准化结构内部

state1.tags.byIds['302'] = { id : 302, name: '旅行' , posts:[102] }

内部帖子[102]的价值,

state1.posts.byIds['102'] = { id : 102 , 标题: '帖子 2', 评论: [202] }

里面的评论[202]值会是这样的

state1.posts.comments['202'] = { id : 202, title: '评论 2' }


因此标签[302]值的标准化输出将是

{ id: 302, name: 'Travel', posts: { id: 102, title: 'Post 2', comments: { id: 202, text: 'comment 2' } } }

但在非标准化结构标签中302值将是

{ id: 302, name: 'Travel', posts: [{ id: 101, title: 'Post 1' }] } 

这两个输出不一样,如何正确规范化以获得相同的输出?

javascript arrays performance object normalization
1个回答
0
投票

你可以使用 normalizr 包,它

根据模式标准化嵌套 JSON

标准化嵌套数据文档提到了这个包。有关更多信息,请参阅 api 文档。

您问题的解决方案:

import { schema, normalize, denormalize } from 'normalizr';

const state = {
  users: [
    {
      id: 1,
      name: 'Alice',
      posts: [
        {
          id: 101,
          title: 'Post 1',
          comments: [
            { id: 202, text: 'comment 2' },
            { id: 201, text: 'comment 1' },
          ],
        },
      ],
    },
    { id: 2, name: 'Bob', posts: [{ id: 102, title: 'Post 2', comments: [{ id: 202, text: 'comment 2' }] }] },
  ],
  tags: [
    {
      id: 301,
      name: 'Tech',
      posts: [
        { id: 101, title: 'Post 1' },
        { id: 102, title: 'Post 2' },
      ],
    },
    {
      id: 302,
      name: 'Travel',
      posts: [{ id: 102, title: 'Post 2' }],
    },
  ],
};

const comment = new schema.Entity(
  'comments',
  {},
  {
    processStrategy: (value, parent) => {
      return { ...value, post: parent.id };
    },
  },
);
const post = new schema.Entity('posts', { comments: new schema.Array(comment) });
const user = new schema.Entity('users', { posts: new schema.Array(post) });
const tag = new schema.Entity('tags', { posts: new schema.Array(post) });

const responseSchema = new schema.Object({ users: new schema.Array(user), tags: new schema.Array(tag) });

const normalizedData = normalize(state, responseSchema);

console.log('normalizedData: ', JSON.stringify(normalizedData, null, 2), '\n');

const tagId = '302';
const denormalizedData = denormalize({ tags: [tagId] }, responseSchema, normalizedData.entities);
console.log('denormalizedData: ', JSON.stringify(denormalizedData, null, 2), '\n');
console.log('tag[302]: ', JSON.stringify(denormalizedData.tags[0], null, 2));

日志:

normalizedData:  {
  "entities": {
    "comments": {
      "201": {
        "id": 201,
        "text": "comment 1",
        "post": 101
      },
      "202": {
        "id": 202,
        "text": "comment 2",
        "post": 102
      }
    },
    "posts": {
      "101": {
        "id": 101,
        "title": "Post 1",
        "comments": [
          202,
          201
        ]
      },
      "102": {
        "id": 102,
        "title": "Post 2",
        "comments": [
          202
        ]
      }
    },
    "users": {
      "1": {
        "id": 1,
        "name": "Alice",
        "posts": [
          101
        ]
      },
      "2": {
        "id": 2,
        "name": "Bob",
        "posts": [
          102
        ]
      }
    },
    "tags": {
      "301": {
        "id": 301,
        "name": "Tech",
        "posts": [
          101,
          102
        ]
      },
      "302": {
        "id": 302,
        "name": "Travel",
        "posts": [
          102
        ]
      }
    }
  },
  "result": {
    "users": [
      1,
      2
    ],
    "tags": [
      301,
      302
    ]
  }
}

denormalizedData:  {
  "tags": [
    {
      "id": 302,
      "name": "Travel",
      "posts": [
        {
          "id": 102,
          "title": "Post 2",
          "comments": [
            {
              "id": 202,
              "text": "comment 2",
              "post": 102
            }
          ]
        }
      ]
    }
  ]
}

tag[302]:  {
  "id": 302,
  "name": "Travel",
  "posts": [
    {
      "id": 102,
      "title": "Post 2",
      "comments": [
        {
          "id": 202,
          "text": "comment 2",
          "post": 102
        }
      ]
    }
  ]
}
© www.soinside.com 2019 - 2024. All rights reserved.