Reduce () method

<%= @topic_view.topic.title %>
<%= @topic_view.topic.average_rating %> <%= @topic_view.topic.posts.count { |p| !!p.custom_fields['rating'] } %>

Hello,

I was doing challenge called “Use the reduce method to analyze data”. I completed it by using filter, map, and reduce methods. Then, I wanted to check what the others did to see if there is a better way to solve this. So, I found some fellow campers solutions to be more efficient and tired to understand the way they solved the problem. However, I got stuck.

Could you please tell me why I am getting “[object Object]8.698.37.9” as a result with the code below? It skips the first index which is 0. What is “[object Object]” ? Why the first word “object” between the brackets starts with lower case(o) and the second starts with capital case(O). When I add “0” at the and of reduce then it gives me the correct sum but I am wondering why?

I checked the reduce function on MDN website and it says like this " If no initialValue is supplied, the first element in the array will be used and skipped." Well, if I don’t use an initial value I can see that the first element is skipped on the example below but it doesn’t add up the rest of the numbers as numbers it just either adds them as text or concatenate them. if your array is just numbers like [1, 2, 3, 4] then you don’t need to provide the initial value, it adds them up correctly.

I am not an experienced person in this field and have no knowledge of any other programming language apart from Java(very basics/fundamentals) but I must say, with JavaScript I am pulling my hair out. In many cases, either I can’t see why the code shouldn’t work or why it shouldn’t return what I expected.

Thank you for your answers

var watchList = [
                 {  
                   "Title": "Inception",
                   "Director": "Christopher Nolan",
                   "imdbRating": "8.8",
                },
                {  
                   "Title": "Interstellar",
                   "Director": "Christopher Nolan",
                   "imdbRating": "8.6",
                },
                {
                   "Title": "The Dark Knight",
                   "Director": "Christopher Nolan",
                   "imdbRating": "9.0",
                },
                {  
                   "Title": "Batman Begins",
                   "Director": "Christopher Nolan",
                   "imdbRating": "8.3",
                },
                {
                   "Title": "Avatar",
                   "Writer": "James Cameron",
                   "imdbRating": "7.9",
                 }
];

let averageRating;

averageRating = watchList.reduce(function(sum, film) {
  return sum + Number(film.imdbRating);
});

console.log(averageRating);
// returns [object Object]8.698.37.9

I’ve edited your post for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make easier to read.

See this post to find the backtick on your keyboard. The “preformatted text” tool in the editor (</>) will also add backticks around text.

Note: Backticks are not single quotes.

The first time the callback is called, accumulator and currentValue can be one of two values. If initialValue is provided in the call to reduce() , then accumulator will be equal to initialValue , and currentValue will be equal to the first value in the array. If no initialValue is provided, then accumulator will be equal to the first value in the array, and currentValue will be equal to the second.

Because you didn’t supply an initial value, sum was initially set to the first item in watchList, which is an object. You are then attempting to add numbers to that object. When you do weird things to an object that JavaScript doesn’t know how to handle it will print [object Object].

2 Likes

Just add an initial value to sum like that:

averageRating = watchList.reduce(function(sum, film) {
  return sum + Number(film.imdbRating);
}, 0);

Thank you for your quick response.

If no initialValue is provided, then accumulator will be equal to the first value in the array" and not the first value of film.imdbRating which is 8.8.

[object Object] is the string representation of an object.

const obj = {}
obj.toString()
"[object Object]"

object is the type and Object is the type of the object (object sub-type Built-in Objects).

Object.prototype.toString.call(new Date)
"[object Date]"

Object.prototype.toString.call([])
"[object Array]"

/* type coercion */
Object.create({}) + 42
"[object Object]42"
2 Likes

lasjorg, thank you for your reply. This is a very useful information.