简体   繁体   中英

How can i combine an array of objects into another array of objects while also combining the common keys

I'm trying sort an array of objects into another array of objects but also combining the common keys (in this case the key updatedAt)

Example:

const arr = [
     { id: '5c65ded933767500010c22a6',
       createdAt: '2019-02-14T21:34:17.181Z',
       updatedAt: '2019-02-14T21:38:01.251Z',
       userId: '5b213937cdcd57002d128aa5',
       phoneNumber: '(514) 578-9586',
       orderId: '5c65ded346e0fb000698f102',
       paymentMethods: [],
       shopName: 'test1',
       amount: 3.47,
       type: 'CASHBACK',
       status: 'COMPLETED',
       currency: 'CAD' },
     { id: '5c5226777de2c4000139de58',
       createdAt: '2019-01-30T22:34:31.648Z',
       updatedAt: '2019-01-30T22:37:01.246Z',
       userId: '5b213937cdcd57002d128aa5',
       phoneNumber: '(514) 578-9586',
       orderId: '5c52267146e0fb0006dc852a',
       paymentMethods: [],
       shopName: 'test2',
       amount: 0.24,
       type: 'CASHBACK',
       status: 'COMPLETED',
       currency: 'CAD' },
     { id: '5c019c07c9e77c0001c5ceb8',
       createdAt: '2018-11-30T20:22:31.392Z',
       updatedAt: '2019-01-17T15:53:24.410Z',
       userId: '5b213937cdcd57002d128aa5',
       phoneNumber: null,
       orderId: '5c019bfcc9e77c0006ba4f77',
       paymentMethods: [],
       shopName: 'test3',
       amount: 1.12,
       type: 'CASHBACK',
       status: 'COMPLETED',
       currency: 'CAD' },
     { id: '5c0195cac9e77c0001c5ceb5',
       createdAt: '2018-11-30T19:55:54.646Z',
       updatedAt: '2019-01-17T15:53:12.624Z',
       userId: '5b213937cdcd57002d128aa5',
       phoneNumber: null,
       orderId: '5c0195bfc9e77c0006b3873f',
       paymentMethods: [],
       shopName: 'test4',
       amount: 1.15,
       type: 'CASHBACK',
       status: 'COMPLETED',
       currency: 'CAD' } ]

into:

[
  {
    date: '2019-01-30T22:37:01.246Z',
    transactions: [
     {'...THE TRANSACTIONS THAT OCURED ON THE SAME DATE...'},
     {'...THE TRANSACTIONS THAT OCURED ON THE SAME DATE...'},
     {'...THE TRANSACTIONS THAT OCURED ON THE SAME DATE...'},
    ]
  },
  {
    date: '2019-01-14T22:37:01.246Z',
    transactions: [
     {'...THE TRANSACTIONS THAT OCURED ON THE SAME DATE...'},
     {'...THE TRANSACTIONS THAT OCURED ON THE SAME DATE...'},
     {'...THE TRANSACTIONS THAT OCURED ON THE SAME DATE...'},
    ]
  }
]

I've tried using multiple loops but it just seems inefficient so i later tried using lodash and that also seems ineficient

here is my attempt using lodash

const mapDaysToTransactions = (transactions) => {
  const mappedTransactions = transactions.reduce((acc, next) => {
  return acc.concat({
    day: next.updatedAt,
    transactions: next
  })
}, [])
const groupedBydays = _.groupBy(mappedTransactions, el => moment(el.day).format('MMMM, d'))
  return Object.keys(groupedBydays).map(d => {
    return {
      date: groupedBydays[d][0].day,
      transactions: _.flattenDeep(groupedBydays[d])
    }
  })
}

I get the expected result with the function above but i want to know if there is a 'better' more optimal way to go about a situation like this.

UPDATE: Another solution using a single reduce

const mapDaysToTransactions = (transactions) => {

  const mapped = transactions.reduce((acc, next) => {
  return acc.concat({
    day: next.updatedAt,
    transactions: next
  })
  }, [])

  return mapped.reduce((acc, transaction) => {
    const date = moment(transaction.day).format('MMMM, d');
    const iso = transaction.day
    const index = acc.findIndex(t => t.date === date);
    const idx = acc.indexOf(date)
  if (idx !== -1) {
    const transactionsByDate = acc[idx];
    const newAcc = [
      ...acc.slice(0, idx),
      ...acc.slice(idx + 1, acc.length),
    ]
    return newAcc.concat({
      date,
      day: iso,
      transactions: transactionsByDate.transactions.concat(transaction),
    });
  }

  return acc.concat({
    date,
    day: iso,
    transactions: [transaction],
  });
 }, []);
}


In reduce you're creating a new array first instead you can use object and group values based on date and than create an array

 const arr = [{ id: '5c65ded933767500010c22a6',createdAt: '2019-02-14T21:34:17.181Z',updatedAt: '2019-02-14T21:38:01.251Z',userId: '5b213937cdcd57002d128aa5',phoneNumber: '(514) 578-9586',orderId: '5c65ded346e0fb000698f102',paymentMethods: [],shopName: 'test1',amount: 3.47,type: 'CASHBACK',status: 'COMPLETED',currency: 'CAD' },{ id: '5c5226777de2c4000139de58',createdAt: '2019-01-30T22:34:31.648Z',updatedAt: '2019-01-30T22:37:01.246Z',userId: '5b213937cdcd57002d128aa5',phoneNumber: '(514) 578-9586',orderId: '5c52267146e0fb0006dc852a',paymentMethods: [],shopName: 'test2',amount: 0.24,type: 'CASHBACK',status: 'COMPLETED',currency: 'CAD' },{ id: '5c019c07c9e77c0001c5ceb8',createdAt: '2018-11-30T20:22:31.392Z',updatedAt: '2019-01-17T15:53:24.410Z',userId: '5b213937cdcd57002d128aa5',phoneNumber: null,orderId: '5c019bfcc9e77c0006ba4f77',paymentMethods: [],shopName: 'test3',amount: 1.12,type: 'CASHBACK',status: 'COMPLETED',currency: 'CAD' },{ id: '5c0195cac9e77c0001c5ceb5',createdAt: '2018-11-30T19:55:54.646Z',updatedAt: '2019-01-17T15:53:12.624Z',userId: '5b213937cdcd57002d128aa5',phoneNumber: null,orderId: '5c0195bfc9e77c0006b3873f',paymentMethods: [],shopName: 'test4',amount: 1.15,type: 'CASHBACK',status: 'COMPLETED',currency: 'CAD' } ] let final = arr.reduce((op,inp) => { let date = inp.updatedAt.substr(0,10) op[date] = op[date] || {date, transaction:[]} op[date].transaction.push(inp) return op },{}) console.log(Object.values(final)) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM