【问题标题】:How to make the property of one array property of another (code optimization)如何使一个数组的属性成为另一个数组的属性(代码优化)
【发布时间】:2020-10-01 06:59:25
【问题描述】:

这就是我所拥有的

const users = [
    { id: 1, name: 'Mike', postIds: [11, 22] },
    { id: 2, name: 'Dan', postIds: [33] },
    { id: 3, name: 'Lance', postIds: [44] },
];

const posts = [
    { id: 11, title: 'How good is he' },
    { id: 22, title: 'How fast is he' },
    { id: 33, title: 'How to make it faster' },
    { id: 44, title: 'How can he do it' },
];

这就是我需要在输出中获得的内容

const expectedResult = [
  {
    id: 1,
    name: 'Mike',
    posts: [
      { id: 11, title: 'How good is he' },
      { id: 22, title: 'How fast is he' },
    ]
  },
  {
    id: 2,
    name: 'Dan',
    posts: [{ id: 33, title: 'How to make it faster' }]
  },
  {
    id: 3,
    name: 'Lance',
    posts: [{ id: 44, title: 'How can he do it' }]
  },
]

这就是我尝试过的。它有效,但它很愚蠢,我认为它可以在一次操作中完成。请检查我可以做些什么使它更干净

const users = [
    { id: 1, name: 'Mike', postIds: [11, 22] },
    { id: 2, name: 'Dan', postIds: [33] },
    { id: 3, name: 'Lance', postIds: [44] },
];

const posts = [
    { id: 11, title: 'How good is he' },
    { id: 22, title: 'How fast is he' },
    { id: 33, title: 'How to make it faster' },
    { id: 44, title: 'How can he do it' },
];

let updUsers = users.map(obj => ({ ...obj,
  posts: [...posts]
}))
const output = updUsers.map(
  user => ({
    ...user,
    posts: user.posts.filter(
      post => user.postIds.includes(post.id)
    )
  })
);
const expectedOut = output.map(({
  id,
  name,
  posts
}) => ({
  id,
  name,
  posts
}))
console.log(expOut)

【问题讨论】:

    标签: javascript ecmascript-6 destructuring


    【解决方案1】:

    将帖子数组转换为帖子 ID 的映射 -> 帖子对象以加快查找速度:

    const postMap = new Map(posts.map((p) => [p.id, p]));
    
    const expectedResult = users.map((u) => {
      const newU = { ...u, posts: u.postIds.map((id) => postMap.get(id)) };
      delete newU.postIds;  // Remove the undesired `postIds` property from the copy
      return newU;
    });
    
    console.log(expectedResult);
    

    【讨论】:

      【解决方案2】:

      您可以在映射users 时过滤posts,而不是将其作为第二次传递。

      const users = [
          { id: 1, name: 'Mike', postIds: [11, 22] },
          { id: 2, name: 'Dan', postIds: [33] },
          { id: 3, name: 'Lance', postIds: [44] },
      ];
      
      const posts = [
          { id: 11, title: 'How good is he' },
          { id: 22, title: 'How fast is he' },
          { id: 33, title: 'How to make it faster' },
          { id: 44, title: 'How can he do it' },
      ];
      
      let expOut = users.map(({id, name, postIds}) => ({ id, name,
        posts: posts.filter(({id}) => postIds.includes(id))
      }))
      
      console.log(expOut)

      【讨论】:

      • OP 的帖子有这种确切的模式。
      • 他在两次给map的电话中做到了这一点,并一次询问了如何做到这一点。
      • @Barmar 先生,您知道我在哪里可以找到一些“相似”的任务吗?想在这多练习
      【解决方案3】:
      • 这是另一种幼稚的方法,但时间复杂度更高。
      • P.S.:时间复杂度为 n^3

      const users = [
          { id: 1, name: 'Mike', postIds: [11, 22] },
          { id: 2, name: 'Dan', postIds: [33] },
          { id: 3, name: 'Lance', postIds: [44] },
      ];
      
      const posts = [
          { id: 11, title: 'How good is he' },
          { id: 22, title: 'How fast is he' },
          { id: 33, title: 'How to make it faster' },
          { id: 44, title: 'How can he do it' },
      ];
      
      let updUsers = users.map(function(obj){
          let postsArr = [];
          for(i=0; i<obj.postIds.length; i++){
              const postArr = posts.find((item) => item.id == obj.postIds[i]);
              postsArr.push(postArr);
          };
      
      
          return{'id':obj.id,'name':obj.name,'posts':postsArr};});
      
      console.log(updUsers);

      【讨论】:

      • 先生,您知道我在哪里可以找到一些“相似”的任务吗?想在这多练习
      • Leetcode.com 和 Freecodecamp.org 是提高实践知识的好平台。
      【解决方案4】:

      您可以先将您的帖子数组转换为键值对并使用Object.fromEntries 获取对象,现在只需映射它。这是一个实现:

      const users = [ { id: 1, name: 'Mike', postIds: [11, 22] }, { id: 2, name: 'Dan', postIds: [33] }, { id: 3, name: 'Lance', postIds: [44] },];
      
      const posts = [ { id: 11, title: 'How good is he' }, { id: 22, title: 'How fast is he' }, { id: 33, title: 'How to make it faster' }, { id: 44, title: 'How can he do it' },];
      
      //convert posts to object and then map it:
      
      const postObjects = Object.fromEntries(posts.map(p=>[p.id, p]));
      
      const result = users.map(({id, name, postIds})=>({id, name, posts:postIds.map(p=>postObjects[p])}));
      
      console.log(result);

      【讨论】:

      • 先生,您知道我在哪里可以找到一些“相似”的任务吗?想在这多练习
      【解决方案5】:

      我们可以使用Array.prototype.reduceArray.prototype..filter 来简化这一过程,并使用Set 为用户找到合适的帖子以便更快地查找:

      const users = [
          { id: 1, name: 'Mike', postIds: [11, 22] },
          { id: 2, name: 'Dan', postIds: [33] },
          { id: 3, name: 'Lance', postIds: [44] },
      ];
      
      const posts = [
          { id: 11, title: 'How good is he' },
          { id: 22, title: 'How fast is he' },
          { id: 33, title: 'How to make it faster' },
          { id: 44, title: 'How can he do it' },
      ];
      
      const mapUsersByPost = (users, posts) => {
        return users.reduce((acc, {id, name, postIds}) => {
         const filteredPosts = posts.filter(({id}) => new Set(postIds).has(id));
         acc.push({ id, name, posts: filteredPosts});
         return acc;
        }, []);
      }
      
      console.log(mapUsersByPost(users, posts));

      【讨论】:

      • 先生,您知道我在哪里可以找到一些“相似”的任务吗?想在这多练习
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 2020-11-03
      • 2016-10-17
      相关资源
      最近更新 更多