Blah blah
Blah blah

Reputation: 394

JavaScript filter method returning filtered array and empty array

I am trying to log the current reading status but instead of getting just the log I am also getting an empty array when calling displayInformation(). How can I get the result I want without an additional empty array? and why is it returning an empty array?

function displayInformation() {
  function statusRead(obj){
    if (obj.readingStatus === false) {
      console.log('You still need to read ' + obj.title + ' by ' + obj.author + '.');
    } else {
      console.log('Already read ' + obj.title + ' by' + obj.author + '.');
    }
  }

  var statusFilter = library.filter(statusRead);
  console.log(statusFilter);
}

var library = [ 
    {
        title: 'Bill Gates',
        author: 'The Road Ahead',
        readingStatus: true
    },
    {
        title: 'Steve Jobs',
        author: 'Walter Isaacson',
        readingStatus: true
    },
    {
        title: 'Mockingjay: The Final Book of The Hunger Games',
        author: 'Suzanne Collins',
        readingStatus: false
    }
];

displayInformation();

When you invoke displayInformation() this is whats logged to console

"Already read Bill Gates byThe Road Ahead."
"Already read Steve Jobs byWalter Isaacson."
"You still need to read Mockingjay: The Final Book of The Hunger Games by Suzanne Collins."
[]

Upvotes: 2

Views: 3286

Answers (2)

Rajaprabhu Aravindasamy
Rajaprabhu Aravindasamy

Reputation: 67207

How can I get the result I want without an additional empty array?

You have to use .forEach() or a normal for loop to do what you want to do. .filter() use case is entirely different from yours.

why is it returning an empty array?

Since the .filter() method will return a filtered array, it is returning an empty array in your case as your callBack function is returning undefined all the time.


Your code should have to be like this,

function displayInformation(library) {
 library.forEach(function(obj){
    if (obj.readingStatus === false) {
      console.log('You still need to read ' + obj.title + ' by ' + obj.author + '.'); 
    } else { 
      console.log('Already read ' + obj.title + ' by' + obj.author + '.'); 
    }
 });
}

displayInformation(library);

The pure for-loop version,

function displayInformation(library) {
  var i = 0, len = library.length, obj;
  for (; i < len; i++) {
    obj = library[i];
    if (obj.readingStatus === false) {
      console.log('You still need to read ' + obj.title + ' by ' + obj.author + '.');
    } else {
      console.log('Already read ' + obj.title + ' by' + obj.author + '.');
    }
  }
}

displayInformation(library);

Upvotes: 3

Mike Cluck
Mike Cluck

Reputation: 32511

That's because you're printing out statusFilter which is the result of filtering using statusRead. Since statusRead never returns true, the result will be empty. The way that filter works is it will create a new array from an old array, where it includes every value that returns truthy. For example, here's how you could get all of the even numbers from a list of numbers.

var evens = numbers.filter(function(x) {
  return x % 2 === 0;
});

So, again, since you are never returning true from your filter predicate, you're getting an empty list which you proceed to console.log out.

To just iterate through a list, you should either use a for loop:

for (var i = 0; i < library.length; i++) {
  var obj = library[i];
  ...
}

Or the forEach method:

library.forEach(function(obj) {
  ...
});

Upvotes: 0

Related Questions