3

I'm trying to learn better use of JS functions and I have a feeling what I'm after can be done using reduce or map or both, but I simply cannot find examples of this particular scenario:

I have an array of objects, eg:

const data =  [
    {
        "member": "111111",
        "offers": 0,
        "categories": 0,
        "total": 100,
        "favorites": 0
    },
    {
        "member": "111111",
        "offers": 2,
        "categories": 1,
        "total": 400,
        "favorites": 1
    },
    {
        "member": "222222",
        "offers": 1,
        "categories": 0,
        "total": 50,
        "favorites": 5
    }
]

The goal is to reduce to an array that merges all the key values into ONE array for each member, ie:

    {
        "member": "111111",
        "offers": 2,
        "categories": 1,
        "total": 500,
        "favorites": 1
    },
    {
        "member": "222222",
        "offers": 1,
        "categories": 0,
        "total": 50,
        "favorites": 5
    },

Therefore, there were two entries for member 111111, they have been merged and all the other values summed into a single array.

Honestly, everything I've tried is a mess, so apart from using the boring for loops or adding code here that is clearly rubbish, I hope you can point me in the right direction.

0

2 Answers 2

4

You can do

const data =  [
    {
        "member": "111111",
        "offers": 0,
        "categories": 0,
        "total": 100,
        "favorites": 0
    },
    {
        "member": "111111",
        "offers": 2,
        "categories": 1,
        "total": 400,
        "favorites": 1
    },
    {
        "member": "222222",
        "offers": 1,
        "categories": 0,
        "total": 50,
        "favorites": 5
    }
]


let result = data.reduce((a, b) => {
  a[b.member] = a[b.member] || {member : b.member};
  for(let property of Object.keys(b)){
    if(property == 'member') continue;
    a[b.member][property] = a[b.member][property] || 0;
    a[b.member][property] += b[property];
  }
  return a;
}, {});

result = Object.keys(result).map(e => result[e]);

console.log(result);

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

2 Comments

that is beautiful JS, exactly what I was after
not to push my luck - but if there's any chance u could explain some of the lines, I would appreciate it - I'm really trying to improve my real understanding :)
2

Heres another example with just a reduce and indexOf

const data =  [
    {
        "member": "111111",
        "offers": 0,
        "categories": 0,
        "total": 100,
        "favorites": 0
    },
    {
        "member": "111111",
        "offers": 2,
        "categories": 1,
        "total": 400,
        "favorites": 1
    },
    {
        "member": "222222",
        "offers": 1,
        "categories": 0,
        "total": 50,
        "favorites": 5
    }
]

const merge = (target, props) => {
  for(p in props){
    if(p !== 'member') {
      target[p] += props[p]
    }
  }
  return target
}

const a = data.reduce((res, d) => {
  const idx = res.findIndex(r => r.member === d.member)
  if (idx >= 0) {
    const newRes = merge(res[idx], {...d})
    res.splice(res[idx], 1, newRes)
  } else {
    res.push(d)
  }
  return res
}, [])

console.log(a)

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.