【问题标题】:push value duplicate into new array将重复值推入新数组
【发布时间】:2020-10-22 13:44:18
【问题描述】:

我有这样的对象数组

const data = [
  { 
     name: "John",
     transaction: "10/10/2010",
     item: "Bag"
  },
  { 
     name: "Steven",
     transaction: "31/10/2020",
     item: "Shoe"
  },
  { 
     name: "John",
     transaction: "18/06/2019",
     item: "Sock"
  }
]

您可以看到该数组中的对象名称重复名称但事务不同

然后我想要这样的结果:

const result = [
  { 
     name: "John",
     transactions: [
         {
            date: "10/10/2010",
            item: "Bag"
         },
         {
            date: "18/06/2019",
            item: "Sock"
         }        
      ]
  },
  { 
     name: "Steven",
     transactions: [
         {
            date: "31/10/2020",
            item: "Shoe"
         }  
      ]
  },
]

所以新数组记录了同一个人的新交易

【问题讨论】:

  • 你尝试过什么来解决这个问题?请与我们分享您的方法/代码(:

标签: javascript arrays loops object ecmascript-6


【解决方案1】:

代码如下:

const data = [
  { 
     name: "John",
     transaction: "10/10/2010",
     item: "Bag"
  },
  { 
     name: "Steven",
     transaction: "31/10/2020",
     item: "Shoe"
  },
  { 
     name: "John",
     transaction: "18/06/2019",
     item: "Sock"
  }
]

let Transactions = []

data.forEach(data => {
       Transactions.some(t => {
            if(t.name === data.name){
            t.transactions.push({date:data.transaction,item:data.item})
            return;
            }
            })

            Transactions.push({
                name:data.name,
                transactions:[
                    {date:data.transaction,item:data.item}
                ]
            })
            console.log(Transactions);
})

array.some 比我认为的 forEach 循环更好。所以决定坚持下去。

【讨论】:

    【解决方案2】:

    请尝试以下示例

    const data = [
      {
        name: "John",
        transaction: "10/10/2010",
        item: "Bag",
      },
      {
        name: "Steven",
        transaction: "31/10/2020",
        item: "Shoe",
      },
      {
        name: "John",
        transaction: "18/06/2019",
        item: "Sock",
      },
    ];
    
    const output = data.reduce((previousValue, { name, transaction, item }) => {
      const index = previousValue.findIndex((entry) => entry.name === name);
    
      if (index === -1) {
        previousValue = [
          ...previousValue,
          {
            name: name,
            transactions: [{ date: transaction, item }],
          },
        ];
      } else {
        previousValue[index].transactions = previousValue[
          index
        ].transactions.concat({
          date: transaction,
          item,
        });
      }
    
      return previousValue;
    }, []);
    
    console.dir(output, { depth: null, color: true });

    【讨论】:

      【解决方案3】:

      一个简单的 reduce 就可以了

      const data = 
            [ { name: 'John',   transaction: '10/10/2010', item: 'Bag'  } 
            , { name: 'Steven', transaction: '31/10/2020', item: 'Shoe' } 
            , { name: 'John',   transaction: '18/06/2019', item: 'Sock' } 
            ] 
           
      const result = data.reduce((a,{name,transaction:date,item})=>
            {
            let x = a.find(e=>e.name===name)
            if (!x) 
              {
              let n = a.push({name, transactions:[]}) -1
              x = a[n]         
              }
            x.transactions.push({date,item})
            return a
            },[])
      
      console.log(result)
      .as-console-wrapper { max-height: 100% !important; top: 0; }

      更短的版本

      const result = data.reduce((a,{name,transaction:date,item})=>
            {
            let x = a.find(e=>e.name===name) || (a[a.push({name, transactions:[]}) -1])       
            x.transactions.push({date,item})
            return a
            },[])
      

      【讨论】:

        【解决方案4】:

        你可以用一种功能性的方式让它可读,下面的工作解决方案是使用ramdajs

        const data = [
          {
            name: 'John',
            transaction: '10/10/2010',
            item: 'Bag'
          },
          {
            name: 'Steven',
            transaction: '31/10/2020',
            item: 'Shoe'
          },
          {
            name: 'John',
            transaction: '18/06/2019',
            item: 'Sock'
          }
        ]
        
        const result = pipe(
          groupBy(obj => obj.name),
          mapObjIndexed((groupObjs, groupName) => ({
            name: groupName,
            transactions: map(
              groupObj => ({
                date: groupObj.transaction,
                item: groupObj.item
              }),
              groupObjs
            )
          })),
          values
        )(data)
        
        console.log(result)
        <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>
        <script>const { groupBy, mapObjIndexed, pipe, map, values } = R</script>

        这是ramdajs doc的链接

        【讨论】:

          【解决方案5】:

          使用 lodash 的 _.groupBy() 函数怎么样?

          const data = [
            { 
               name: "John",
               transaction: "10/10/2010",
               item: "Bag",
            },
            { 
               name: "Steven",
               transaction: "31/10/2020",
               item: "Shoe",
            },
            { 
               name: "John",
               transaction: "18/06/2019",
               item: "Sock",
            }
          ]
          
          const result = _.groupBy(data, "name")
          console.log(result)
          &lt;script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"&gt;&lt;/script&gt;

          【讨论】:

            猜你喜欢
            • 2021-01-14
            • 2021-08-29
            • 2013-03-31
            • 2017-03-28
            • 2016-05-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多