【问题标题】:Append property from two arrays of objects从两个对象数组追加属性
【发布时间】:2021-09-16 08:24:57
【问题描述】:

在 JavaScript 中,我有两个数组 - arr1arr2

arr1是一个对象数组,如下图-

[
   { user: {id: 1, name: "name1", role: "A"} },
   { user: {id: 2, name: "name2", role: "B"} },
   { user: {id: 3, name: "name3", role: "A"} }
]

arr2 也是一个对象数组:

[
   { id: 2, username: "brad", ... },
   { id: 1, username: "colly", ... },
   { id: 3, username: "sophie", ... }
]

现在,我想得到这样的输出 arr1 -

[
   { user: {id: 1, name: "name1", role: "A", username: "colly"} },
   { user: {id: 2, name: "name2", role: "B", username: "brad"} },
   { user: {id: 3, name: "name3", role: "A", username: "sophie"} }
]

基本上,如果arr1[0].user.id = arr2[1].id 则将username 属性从arr2 添加到userid。整个数组都一样,然后最后返回原始数组arr1,并将username附加到每个相应的user对象。

希望您能理解我试图解释的内容。提前致谢。

【问题讨论】:

    标签: javascript arrays oop


    【解决方案1】:

    您可以在您的情况下使用mapfind

    const arr1 = [
      { user: { id: 1, name: "name1", role: "A" } },
      { user: { id: 2, name: "name2", role: "B" } },
      { user: { id: 3, name: "name3", role: "A" } },
    ];
    
    const arr2 = [
      { id: 2, username: "brad" },
      { id: 1, username: "colly" },
      { id: 3, username: "sophie" },
    ];
    
    const output = arr1.map(el => ({
      user: { ...el.user, username: arr2.find(x => x.id === el.user.id).username },
    }));
    
    console.log(output);

    【讨论】:

      【解决方案2】:

      这应该可以解决问题:

      const arr1 = [
        { user: {id: 1, name: "name1", role: "A"} },
        { user: {id: 2, name: "name2", role: "B"} },
        { user: {id: 3, name: "name3", role: "A"} }
      ];
      
      const arr2 = [
        { id: 2, username: "brad", ... },
        { id: 1, username: "colly", ... },
        { id: 3, username: "sophie", ... }
      ]
      
      mergedArray = arr1.map(e => {
        return {
          user: {
            ...e.user,
            username: arr2.find(x => x.id === e.user.id).username
          }
        }
      })
      

      如果您想合并更多的值而不仅仅是用户名,您可以将在 arr2 中找到的值保存在一个变量中:

      mergedArray = arr1.map(e => {
        const match = arr2.find(x => x.id === e.user.id);
        return {
          user: {
            ...e.user,
            username: match.username,
            someOtherValue: match.someOtherValue
          }
        }
      })
      

      如果不确定arr2中的对象是否包含用户名,则在函数中访问用户名时会出错,username: match?.username ?? 'fallbackValue'将防止错误并返回默认值以防万一,如果没有默认值需要的可以留下?? '...'部分

      【讨论】:

        【解决方案3】:

        鉴于您的两个数组,您需要这样做:

        // loop through all the elements in arr1    
        const result = arr1.map(element => {
              // Search the element by ID in arr2 (You need to loop every time, probably not the better solution.
              // Maybe better with a Map
              const elInArr2Found = arr2.find(arr2Element => arr2Element.id === element.user.id);
              // If the element is found, set the property "username" to the element
              // If the element is not found, leave it as is
              if (elInArr2Found !== undefined) {
                element.user.username = elInArr2Found.username;
              }
              // return the element
              return element;
            })
        

        result 将设置用户名的所有元素。

        检查Map documentation 以避免嵌套循环。

        【讨论】:

          【解决方案4】:

          只对每个数组进行一次迭代的最有效方法是将 arr2 映射到一个对象或使用 id 作为键的 Map,然后遍历 arr1 并查找每个 id 以获取用户名。

          对象或 Map 查找是 o(1) 操作,而 find() 等方法需要 arr2 的多次迭代

          const arr1=[{user:{id:1,name:"name1",role:"A"}},{user:{id:2,name:"name2",role:"B"}},{user:{id:3,name:"name3",role:"A"}}],
            arr2=[{id:2,username:"brad"},{id:1,username:"colly"},{id:3,username:"sophie"}];
          
          const arr2Names = new Map(arr2.map(e => [e.id, e.username]));
          
          arr1.forEach(({user}) => user.username = arr2Names.get(user.id))
          
          console.log(arr1)

          【讨论】:

          • 很好的答案,我知道有一种方法可以在不遍历两个数组的情况下做到这一点,只是当时想不到。
          • @sschwei1, const arr2Names = new Map(arr2.map(e => [e.id, e.username])); 我想你已经在这里用arr2.map() 循环了arr2 ......到目前为止,我知道不循环两个数组是不可避免的......
          • @ikhvjs 他正在循环一次arr1,但他避免多次循环arr2(嵌套循环)。
          • @ikhvjs 对不起,我在考虑 o-notations,2n 被缩短为 n,所以我说loop through 1 array,我真正想说的是,避免嵌套循环并且复杂性是从 n² -> n 减少
          • @sschwei1,不用担心。我现在明白你的意思了。谢谢。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-02-27
          • 2020-01-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多