19

I am taking a cool online course about functional programming in JavaScript. I was following along just fine until the instructor used the Array.prototype.reject() and it did not work for me at run time.

I would like to use "reject" instead of a for loop because it is less code. But, my browser, NodeJS and Express Code consoles tell me that reject is not a function.

I researched other articles that discuss promise.reject is not a function, but provide solutions that do not make sense to my scenario.

Here is the example code in the course:

var animals = [
    { name: 'Fluffykins',   species: 'rabbit' },
    { name: 'Caro',         species: 'dog' },
    { name: 'Hamilton',     species: 'dog' },
    { name: 'Harold',       species: 'fish' },
    { name: 'Ursula',       species: 'cat' },
    { name: 'Jimmy',        species: 'fish' }
];


var isDog = function(animal){
    return animal.species === 'dog';
}

var otherAnimals = animals.reject(isDog);

The work-around with a for-loop:

var notDogs = animals.filter(function(animal){
    return animal.species !== 'dog';
});

Its output is:

> notDogs
[ { name: 'Fluffykins', species: 'rabbit' },
  { name: 'Harold', species: 'fish' },
  { name: 'Ursula', species: 'cat' },
  { name: 'Jimmy', species: 'fish' } ]

Please help me use Array.prototype.reject().

EditL

I found Array.prototype.reject() at GitHub/Array.prototype.reject)

JVDL
  • 1,157
  • 9
  • 16
host_255
  • 361
  • 2
  • 7
  • 18
  • What IS your JS version? Perhaps [reject is not supported](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject#Specifications) – mplungjan Nov 13 '16 at 11:11
  • 3
    Well, arrays do not have a `.reject` method mainly because they are not promises, so I'm not sure why you expect that code to work. – VLAZ Nov 13 '16 at 11:18
  • I'm not clear about your question. Do you want to solve this problem using `reduce`? – zhuscat Nov 13 '16 at 11:27
  • I run Firefox 49.0.2, Chrome 54.0.2840.87 m (64-bit) and NodeJS v6.9.1. I also tried it in Firefox Developer Edition 51.0a2 (2016-11-12) (32-bit) with the same result. [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Not_a_function) says: "It was attempted to call a value like a function, but the value is not actually a function. Some code expects you to provide a function, but that didn't happen. Maybe there is a typo in the function name? Maybe the object you are calling the method on does not have this function?...." So, what is wrong with my code, I wonder – host_255 Nov 13 '16 at 11:30
  • @zhuscat I would like to use reduce instead of the for-loop. – host_255 Nov 13 '16 at 11:30
  • @host_255 what would you like to achieve with [`reduce`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce)? It isn't clear why you want to use reduce because your example shows that you want to filter/reject some items from your array and that's just not what `reduce` is (typically) used for, hence some of the answers giving you filter/_.reject suggestions. Take a look at the [documentation for reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) and see if that's what you actually want. – JVDL Nov 13 '16 at 11:35
  • All of these higher order functions are looping over the array items `map`, `reduce`, `filter`, `reject`, so what do you mean by instead of the for loop? because I'm little confused because you mentioned **The work-around with a for-loop:** and used `.filter` so for sure you don't mean imperative/declarative? – Saad Shahd Nov 13 '16 at 11:40
  • @host_255 I answered this question. Hope it meets your requirement. – zhuscat Nov 13 '16 at 11:43
  • @Dymos reduce was a total typo. I apologize. I am only trying to accomplish something with `reject` – host_255 Nov 13 '16 at 11:48
  • @host_255 again, there isn't a `.reject` for arrays in JavaScript. Why do you expect there is? – VLAZ Nov 13 '16 at 11:53
  • @vlaz This instructor used it in an example to show a prototype that does the inverse of `filter`. I found `Array.prototype.reject` in GitHub and can add the prototype to my `package.json` file or run `npm install prototypes`. However, I still found issues when testing my code in Firefox, Chrome and NodeJS consoles, so I will be using something like what @Dymos mentioned in that answer. – host_255 Nov 13 '16 at 12:09
  • @host_255 no worries it happens :) ... The reason you're still seeing problems between environments is probably because you installed a dependency for your server side (NodeJS) stuff but not the front end (browser) stuff. They run independently of each other. – JVDL Nov 13 '16 at 12:24
  • 4
    The "online course" you are talking about is the "Fun Fun Function" YouTube channel (https://www.youtube.com/channel/UCO1cgjhGzsSYb1rsB4bFe4Q). It is actually a fabulous channel with lots of great content. The host, MPJ, also recently took over the DevTips YouTube channel (https://www.youtube.com/user/DevTipsForDesigners) from Travis. I recomment these channels to anyone with an interest in JavaScript. – Anthony Gatlin Apr 29 '18 at 16:45

8 Answers8

26

Array.prototype.reject isn't a thing unless a library/custom code adds the reject method to Arrays.

To achieve what you want, you should use the Array.prototype.filter method like you already are. I'm not sure what you think is longer about it because you can write it the same way:

var animals = [
  { name: 'Fluffykins', species: 'rabbit' }, 
  { name: 'Caro', species: 'dog' }, 
  { name: 'Jimmy', species: 'fish' }
];

function noDogs(animal) {
  return animal.species !== 'dog';
}

var otherAnimals = animals.filter(noDogs);
console.log(otherAnimals);
JVDL
  • 1,157
  • 9
  • 16
23

As mentioned in another answer, this was mentioned in a youtube series about functional programming. The video uploader did correct this mistake with an annotation, but you may not have seen that if you were viewing the video on a mobile device.

enter image description here

Conor Pender
  • 1,071
  • 1
  • 14
  • 30
7

Array.prototype.reject does not exist in vanilla JavaScript.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array

It seems that you were using the example provided by funfunfunction: https://www.youtube.com/watch?v=BMUiFMZr7vk

Notice he never actually executes any of the code he demonstrates in this video.

As others have said, reject does exist in lodash/underscore, or the same result can be derived from using filter, as Dymos suggests.

thepaulstella
  • 71
  • 2
  • 2
4

The reject function is like .filter but in reverse, so you can. You can use the filter function and reverse the callback with the Logical Operator NOT to reverse the outcome.

Array.prototype.reject = function(fn){return this.filter(x => !fn(x))}
  • fn is the callback

  • this. is the array that the reject function has been called on.

  • x is the current entry of that array

Timar Ivo Batis
  • 1,861
  • 17
  • 21
2

For quick & dirty work!

Array.prototype.reject = function(fn) {
 let rej = test => !fn(test);
 return this.filter(rej);
};
Moos
  • 535
  • 1
  • 4
  • 8
0

You can find _.reject at lodash/underscore

I think that You can use Array.prototype.reduce without any problem but the thing here is that you're mixing between reduce and reject.

reject produces an array without the rejected elements the opposite of filter.

reduce produces a totally new one item value from a list of items

Examples:

function even(number) {
  return number % 2 === 0;
}

_.reject([1, 2, 3, 4], even); // [1, 3]
_.filter([1, 2, 3, 4], even); // [2, 4]

// reduce is totally different method
_.reduce([1, 2, 3, 4], function(total, current) {
  return total + current;
}, 0); // 10
Saad Shahd
  • 963
  • 7
  • 10
  • 1
    when you said that `Array.prototype.reduce()` is not a thing, I checked out [GitHub](https://github.com/thejameskyle/Array.prototype.reject) and found it there. Thank you for breaking that down for me. Reduce was a type of mine. My apologies. – host_255 Nov 13 '16 at 11:39
  • Hey man, reduce is a thing. reject is not. You need distinguish between both of them. re (duce) - re (ject) – Saad Shahd Nov 13 '16 at 11:47
0

Let's have a look at this array as an example

    const animals = [
    {name: 'Sheru', species: 'Dog' },
    {name: 'Manya', species: 'Cat' },
    {name: 'Monya', species: 'Dog' },
    name: 'Dolly', species: 'fish' }
   ]

We can create a reject function something like this and use

 Array.prototype.reject = function (callback) {
            return this.filter((each, index, array) => !callback(each, index, array))
 }

# We can use something like this to test it


const result = animals.reject((each) => each.species == 'Dog');

console.log(result);
Seeta Ram Yadav
  • 847
  • 9
  • 16
0

As mentioned in another answer, reject is not built-in, but can be used through underscore.js or a similar library. For example, here's what it looks like

Initially install underscore through npm

npm install -d underscore

Then import it while writing your code

const _ = require("underscore");

var animals = [
    {name: "tommy",species: "dog",},
    {name: "Jimmy",species: "rabbit",},
    {name: "bruno",species: "dog",},
    {name:"meow",species:"cat"}
];

var isDog = (x) => x.species === "dog";

var otherAnimals = _.reject(animals, isDog);

console.table(otherAnimals);

Here is how the output looks like

┌─────────┬─────────┬──────────┐
│ (index) │  name   │ species  │
├─────────┼─────────┼──────────┤
│    0    │ 'Jimmy' │ 'rabbit' │
│    1    │ 'meow'  │  'cat'   │
└─────────┴─────────┴──────────┘