2

I am so ridiculously lost with JS...I've been trying literally for hours to do stuff that takes 5 seconds to do in R or Python. Trying to learn just for this one homework.

Lets say I have an object like this:

myObject = [ {'location': 'california', 'day': 'wednesday', 'company': 'Tesla'},
             {'location': 'washington', 'day': 'tuesday', 'company': 'Microsoft'},
             {'location': 'california', 'day': 'wednesday', 'company': 'Tesla'},
             {'location': 'california', 'day': 'monday', 'company': 'Apple'},
             {'location': 'california', 'day': 'monday', 'company': 'SalesForce'}
             {'location': 'washington', 'day': 'tuesday', 'company': 'Microsoft'},
             {'location': 'california', 'day': 'wednesday', 'company': 'Apple'}
            ]

I want to group by location and day, and count the number of different companies and get an output like this:

myOutputObject = [ {'location': 'california', 'day': 'wednesday', 'count':2},
                   {'location': 'washington', 'day': 'tuesday', 'count':1},
                   {'location': 'california', 'day': 'monday', 'count':2}
                 ]

Coming from a python background JS is a nightmare in a box to me.

I tried just creating a 'count' key in every element and setting it 0 to start with like this:

var dataset = []
dataset = data.forEach(function(d){
     d['count'] = 0;
     return d
})
console.log(dataset);

Nothing...zilch...undefined...

Can someone please be kind enough to explain to me how to get my head around this nonsense?

2 Answers 2

3

You could use reduce

const myObject = [
  { location: 'california', day: 'wednesday', company: 'Tesla' },
  { location: 'washington', day: 'tuesday', company: 'Microsoft' },
  { location: 'california', day: 'wednesday', company: 'Tesla' },
  { location: 'california', day: 'monday', company: 'Apple' },
  { location: 'california', day: 'monday', company: 'SalesForce' },
  { location: 'washington', day: 'tuesday', company: 'Microsoft' },
  { location: 'california', day: 'wednesday', company: 'Apple' }
]

const res = myObject.reduce((acc, obj) => {
  const existingIndex = acc.findIndex(
    el => el.location === obj.location && el.day === obj.day
  )
  if (existingIndex > -1) {
    acc[existingIndex].count += 1
  } else {
    acc.push({
      location: obj.location,
      day: obj.day,
      count: 1
    })
  }
  return acc
}, [])

console.log(res)

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

Comments

1

Your start wasn't bad. However, Array.forEach [docs] returns undefined (+ you were actually updating the original object not adding into the new one). So to fix your start, one has to do:

var myOutputObject = [];
myObject.forEach(function(d) {
  myOutputObject.push({...d, count: 0});
})
console.log(myOutputObject);

(Docs for ... operator)

To extend answer provided by hgb123, let's make a solution that doesn't have quadratic time complexity:

const myObject = [
  {location: 'california', day: 'wednesday', company: 'Tesla'},
  {location: 'washington', day: 'tuesday', company: 'Microsoft'},
  {location: 'california', day: 'wednesday', company: 'Tesla'},
  {location: 'california', day: 'monday', company: 'Apple'},
  {location: 'california', day: 'monday', company: 'SalesForce'},
  {location: 'washington', day: 'tuesday', company: 'Microsoft'},
  {location: 'california', day: 'wednesday', company: 'Apple'},
];

const m = new Map();
myObject.forEach(({day, location}) => {
  // Create a key with values that we want to group by
  // A list of key-value pairs is chosen to make use of `Object.fromEntries` later
  const hash = JSON.stringify([['day', day], ['location', location]]);
  m.set(hash, (m.get(hash) || 0) + 1);
});
const myOutputObject = [...m].map(([rec, count]) => ({
  ...Object.fromEntries(JSON.parse(rec)),
  count,
}))
console.log(JSON.stringify(myOutputObject));

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.