Challenge 11 Megathread

Welcome to challenge 11! Use this thread for any and all questions relating to challenge 11.

1 Like
const busTimes = buses => {
  return Object.keys(buses).reduce((acc, cv) => {
    return { ...acc, [cv]: buses[cv].distance / buses[cv].speed };
  }, {});
}

Here is my solution!

1 Like

Had a bit of trouble understanding exactly what your code was doing, so I ended up with this somewhat less-elegant solution that still functions fine.

Capture

3 Likes

Nice! I don’t quite understand what’s going on in your solution though.

Here’s mine:

const busTimes = buses => {
  Object.keys(buses).forEach(dest=>{
    buses[dest]=(buses[dest].distance/buses[dest].speed);
  });
  return(buses);
};

Edit: Solution using the suggested hint, for - in loop, is nearly the same.

const busTimes = buses => {
  for (var dest in buses){
    buses[dest]=(buses[dest].distance/buses[dest].speed)
  }
  return (buses);
};
2 Likes

Not understood what is buses [dest], the key or the value?

1 Like

One liner(ish). Using Object.prototype.entries

const busTimes = buses => Object.entries(buses).reduce((dic,[key, value]) => ({
  ...dic,
  [key]: value.distance / value.speed
}),{})
2 Likes

for each buses[dest] will be the same as buses[name_of_the_first_property_in_the_given_object].
“buses” here can be changed to another name so u wont end misplacing it with the original buses object, but for that u should create a var newobject = {}

I did this

const busTimes = buses => {
  let timeObj = {};
  for (let bus in buses) {
    timeObj[bus] = buses[bus].distance / buses[bus].speed;
  }
  return timeObj;
}
1 Like

Tip: you don’t need to use parentheses when returning, just write it like this: return buses; :wink:

Inelegant is sometimes the better solution. New programmers having trouble with the quesiton can easily learn from it.

1 Like

Nice! Great minds think alike!

Solution

22%20AM

Decided to provide resources for everything that I used in my solution to help those that might not understand what is going on.

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
const obj = { a: 1, b: 2 };

Object.entries(obj); // [["a", 1], ["b", 2]]

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
const arr = [1, 2, 3];
const cbsum = (acc, e) => acc + e;
const acc = 0;

arr.reduce(cbsum, acc); // 6

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Object_destructuring
// See: Unpacking fields from objects passed as function parameter
const nums = { a: 1, b: 2 };
const add = ({ a, b }) => a + b;

add(nums); // 3

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Object_destructuring
// See: Combined Array and Object Destructuring
const place = ['Tokyo', { country: 'Japan', population: 126000000 }];
const whatIs = ([city, { country, population }]) => `The city is ${city}. Located in the country of ${country} and has a population of ${population}.`;

whatIs(place); // The city is Tokyo. Located in the country of Japan and has a population of 126000000.

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Grouping
const singleLineObjReturn = () => ({});
const multiLineObjReturn = () => {
const aaa = {};

return aaa;
};

singleLineObjReturn(); // {}
multiLineObjReturn(); // {}

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
const objA = { abs: 3, int: 21 };
const objB = { ...objA, time: 1000 };

console.log(objB); // { abs: 3, int: 21, time: 1000 }

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer
// See: Computed Property Names
const computedPropertyName = 'two';
const myObj = { a: 1 };

myObj[computedPropertyName] = 2;

console.log(myObj); // { a: 1, two: 2 }
1 Like

Okay~~ I am losing here completely.
Can someone tell me what the dest is?
I googled it and not yet understand so far.

Thanks~

The forEach method actually uses a function to loop over entries in an array.

Let me explain with code:

const list = ['hello', 'world']  // Our array, consisting of 2 entries.

// We loop over all entries in the array like this:
list.forEach(entry => {
  // 'entry' now has the value "hello" the first time, then "world" the second time, etc
  console.log(entry) // 'hello', then 'world'
})

Doe that make more sense?

@TheDutchCoder it makes sense now~

Thank you~~

1 Like
const busTimes = buses =>
  Object.entries(buses).reduce(
    (returnObject, [busStopName, { distance, speed }]) => ({
      ...returnObject,
      [busStopName]: distance / speed
    }),
    {}
  );

So, the object buses looks like:

{
  "pickadilly": {
    "distance": 10,
    "speed": 5
  },
  "uptown": {
    "distance": 13,
    "speed": 10
  }
}

Object.entries(buses) returns an array of [key, value] pairs from the object buses that looks like:

[
  [ // object 1
    "pickadilly", // object 1 key
    {
      "distance": 10, // obj1 value
      "speed": 5
    }
  ],
  [
    "uptown",
    {
      "distance": 13,
      "speed": 10
    }
  ]
]

Now, since it’s an array now, we can use reduce on it! :slight_smile:

Reduce iterates over an array and “collects” all entries in an object. The first argument to reduce function is returnObject that we want to collect our entries to, it is initialized later as {}. The second argument is an entry from our object-turned-into-array that uses destructuring:
[busStopName, { distance, speed }] means: ‘take an array, first element is called bustStopName, and the second one is an object with two properties: distance and speed’

The function itself returns an object every time it runs: ({}). We have to wrap curly braces to braces so it is perceived as an object by JavaScript.

So inside we take returnObject and spread (copy) its properties to this new object with the spread operator ... (first time the function runs, it’s an empty object, so it spreads nothing), and then add another one [busStopName]: distance / speed

[busStopName] is in brackets, so this property name is calculated dynamically at runtime (without the brackets, it would always be literally busStopName all the time)

2 Likes

Nice!
I have a similar solution as follows:

const busTimes = buses => {
  var ret = {};
  if (buses) {
    Object.keys(buses).forEach( (item) => {
      ret[item] = buses[item].speed > 0 ? (buses[item].distance / buses[item].speed) : 0;
    });
  }
  return ret;
};

Accidentally thought that I had to return a nested object like the incoming buses object. Re-read the challenge and noticed my mistake! Solution below for anyone curious:

Summary
const busTimes = buses => {

//Intialize emtpy object
arrivalTimes = {}

//Loop through each bus in list
for (bus in buses){

//Store time and distance for current bus   
var distance= buses[bus].distance
var speed= buses[bus].speed

//Calc TIME and store as key:value pair
arrivalTimes[bus]= distance/speed

}

return arrivalTimes

}
2 Likes

love the challenge very good