0

I have an array that looks like this :

[ 

  { id: 9,
    email: '[email protected]',
    product: 'handbag',
    date: 2019-03-11 },
  { id: 10,
    email: '[email protected]',
    product: 'handbag',
    date: 2019-03-11 },
  { id: 11,
    email: '[email protected]',
    product: 'handbag',
    date: 2019-03-11 },
  { id: 12,
    email: '[email protected]',
    product: 'handbag',
    date: 2019-03-11 },
  { id: 13,
    email: '[email protected]',
    product: 'joystick',
    date: 2019-03-11 },

    etc...............


]

NOTE keys of objects in array are static, but values are dynamic except for email => the email is static

NOTE2 the length of array are dynamic not static, so the number of objects are dynamic

how to filter this array to get the result like this

{
    email: '[email protected]', // email here is static AKA is known
    handbag: 4, // keys here , not just keys they are the values of keys in objects in array , and i want to use them like has access to them
    smartphone: 1,
    joystick: 1,

    etc.......
}

So the final line of out put to the client to be something like this:

You have 4 products of handbag and 1 product of joystick and 1 product of smartphone etc.................

NOTE I don't know the length of the last object , and i don't know the length of array, all data are dynamic except for email.

This question, I think it's a little bit of challenge.

4
  • what is the key? you got a static email, why not use it as hash? Commented Mar 12, 2019 at 18:59
  • @NinaScholz i get this data from db, so i filtered where email, now i use this email to get data from products table. the product table has the above array and objects for this specific user. and i want to put all available data to his front end in one line of code so mapping and loop function won't work Commented Mar 12, 2019 at 19:02
  • please add the wanted result of the above data. and the code, you tried. Commented Mar 12, 2019 at 19:05
  • @NinaScholz updated the question with the desired result Commented Mar 12, 2019 at 19:08

2 Answers 2

2

You can reduce like this:

const data = [{ id: 9,email: '[email protected]',product: 'handbag',date: 2019-03-11 },{ id: 10,email: '[email protected]',product: 'handbag',date: 2019-03-11 },{ id: 11,email: '[email protected]',product: 'handbag',date: 2019-03-11 },{ id: 12,email: '[email protected]',product: 'handbag',date: 2019-03-11 },{ id: 13,email: '[email protected]',product: 'joystick',date: 2019-03-11 }];
const result = data.reduce((acc, {product}) => (acc[product] = (acc[product]||0)+1, acc),
                           { email: data[0].email });
console.log(result);

const phrase = `${result.email} you have in your account ${
    Object.entries(result).map(([k, v]) => k!=="email" && `${v} ${k}${v>1?"s":""}`)
          .filter(Boolean).join(" and ")
}`;
console.log(phrase);

The first part of the code uses reduce, and the comma operator so that the so-called accumulator is returned after the assignment to acc[product] is made.

The ||0 is needed when acc[product] does not yet exist, and then the counting must start from 0.

{ email: data[0].email } is the initial value of the accumulator that reduce builds on. It is the start of the object that will be extended with the other properties.

Sign up to request clarification or add additional context in comments.

3 Comments

great now i want to put this dynamic obj in one line of output as result to appear to client
great thank you this help me , and solved my issue , i just wanted to ask you do you have any reference so i can read to understand more about this line of code data.reduce((acc, {product}) => (acc[product] = (acc[product]||0)+1, acc), { email: data[0].email });
Added some explanation.
2

Use reduce to reduce the array down to an object.

const items = [ 

  { id: 9,
    email: '[email protected]',
    product: 'handbag',
    date: 2019-03-11 },
  { id: 10,
    email: '[email protected]',
    product: 'handbag',
    date: 2019-03-11 },
  { id: 11,
    email: '[email protected]',
    product: 'handbag',
    date: 2019-03-11 },
  { id: 12,
    email: '[email protected]',
    product: 'handbag',
    date: 2019-03-11 },
  { id: 13,
    email: '[email protected]',
    product: 'joystick',
    date: 2019-03-11 }
]

let result = items.reduce((obj, itm) => {
  obj.email = itm.email
  obj[itm.product] = obj[itm.product] + 1 || 1
  return obj
}, {})

let str = []

Object.entries(result).forEach(entry => {
  if(entry[0] == 'email') return
  str.push(`${entry[1]} products of ${entry[0]}`)
})

document.body.innerHTML = `You have ${str.join(' and ')}`

2 Comments

great now i want to put this dynamic obj in one line of output as result to appear to client
I have updated the answer to display the results on the page

Your Answer

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