1

I have an array of JSON objects. However, some of the data is repeated. Is there a way to restructure the array to exclude repeated values? Do I have to use the Map function? or a for loop?

userData = [{id:'101', Time:'3:00pm', Date:'5/25/20'},
            {id:'101', Time:'5:00pm', Date:'5/25/20'},
            {id:'101', Time:'5:00pm', Date:'6/25/20'},
            {id:'105', Time:'1:00pm', Date:'3/25/20'},
            {id:'105', Time:'5:00pm', Date:'5/25/20'}
           ]

Is it possible to restructure the data like so?

userData = [ {id:'101', Time:['3:00pm','5:00pm'], Date:['5/25/20', '6/25/20']},
             {id:'105', Time:['1:00pm','5:00pm'], Date:['3/25/20','5/25/20']}
           ]

If you have any guidance or direction, it would be greatly appreciated! Thank you!

4
  • Do some research into generating a "groupBy" object from array Commented May 25, 2020 at 23:35
  • 2
    Do you really want to group and de-duplicate Time and Date separately? In my experience, in most use cases times make sense only on a certain day. Commented May 25, 2020 at 23:50
  • Seems like it would actually break the data wouldn't it? De-duped Time without Date context would be broken? Commented May 25, 2020 at 23:56
  • Thank you everyone for your responses. I would love to display all times and dates regardless if they correspond. As long as they do not repeat. Again, thank you for your help. Commented May 26, 2020 at 0:02

4 Answers 4

1
let userData = [{id:'101', Time:'3:00pm', Date:'5/25/20'},
        {id:'101', Time:'5:00pm', Date:'5/25/20'},
        {id:'101', Time:'5:00pm', Date:'6/25/20'},
        {id:'105', Time:'1:00pm', Date:'3/25/20'},
        {id:'105', Time:'5:00pm', Date:'5/25/20'}
       ]

let formattedUserData = {}

userData.forEach(user=>{
  if(!formattedUserData[user.id]) formattedUserData[user.id]= {
    id: user.id,
    Time: [],
    Date: [],
  }
  formattedUserData[user.id].Time.push(user.Time)
  formattedUserData[user.id].Date.push(user.Date)
})

const finalResponse = Object.entries(formattedUserData).map((e) => ( { ...e[1] } ));
console.log("finalResponse",finalResponse)
Sign up to request clarification or add additional context in comments.

Comments

1

EDIT: fixed to filter duplicate DateTimes maintaining corresponding order by using a Set() of DateTime strings

Note: optional chaining ?. requires Chrome 80+ and Safari 13+. Use ternary check for undefined if you need compatibility.

Use object map to track duplicate id, concat to Time array if found.

userData = [{id:'101', Time:'3:00pm', Date:'5/25/20'},
            {id:'101', Time:'5:00pm', Date:'5/25/20'},
            {id:'101', Time:'5:00pm', Date:'6/25/20'},
            {id:'105', Time:'1:00pm', Date:'3/25/20'},
            {id:'105', Time:'5:00pm', Date:'5/25/20'}
           ]
console.log(
Object.values(
userData.reduce((acc,{Time, id, Date})=>
  // [id] exists and does not contain DateTime
  acc[id]?.TD?.has(`${Date}_${Time}`)!== true ? 
  Object.assign(acc, {[id]:{
      id, 
      TD: (acc[id]?.TD||new Set()).add(`${Date}_${Time}`),
      Time: (acc[id]?.Time||[]).concat(Time),
      Date: (acc[id]?.Date||[]).concat(Date)
   }})
   : acc,{})
)
// get rid of TD Set, used only to prevent dupes
.map(({TD, ...o})=>o)
)

1 Comment

The expected result requires to de-duplicate the Time and Date arrays, so your answer is not (yet) 100% accurate.
0

I done that:

const userData = 
    [ { id: '101', Time: '3:00pm', Date: '5/25/20'} 
    , { id: '101', Time: '5:00pm', Date: '5/25/20'} 
    , { id: '101', Time: '5:00pm', Date: '6/25/20'} 
    , { id: '105', Time: '1:00pm', Date: '3/25/20'} 
    , { id: '105', Time: '5:00pm', Date: '5/25/20'} 
    ] 
      
const result = userData.reduce((a,{id,Time,Date})=>{
  let el = a.find(ud=>ud.id===id)
  if (!el) { el = {id, Time:[], Date:[]};  a.push(el) }
  if (!el.Time.includes(Time)) el.Time.push(Time)
  if (!el.Date.includes(Date)) el.Date.push(Date)
  return a
  }, [])

console.log( JSON.stringify(result,0,2) )
.as-console-wrapper { max-height: 100% !important; }

Comments

0

According to MDN, Map is a better fit than using an Object. Sets are used to ensure all values are deduplicated.

userData = [{id:'101', Time:'3:00pm', Date:'5/25/20'},
            {id:'101', Time:'5:00pm', Date:'5/25/20'},
            {id:'101', Time:'5:00pm', Date:'6/25/20'},
            {id:'105', Time:'1:00pm', Date:'3/25/20'},
            {id:'105', Time:'5:00pm', Date:'5/25/20'},
           ];

const structure = new Map();

userData.forEach(el => {
  const {t, d} = structure.get(el.id) || {t: new Set(), d: new Set()};
  structure.set(el.id, { t: t.add(el.Time), d: d.add(el.Date) });
});

const restructured = 
  [...structure].map(el => ( {id: el[0], Time: [...el[1].t], Date: [...el[1].d]} ))

console.log(restructured)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.