javascriptarraysunderscore.js

Arguments object not working on Underscore first type function


For an exercise, I have to reproduce the first function from the Underscore.js library.

The code I wrote passes all the tests, except "should work on an arguments object".

I passed these tests:

I failed this test: should work on an arguments object

_.first = function (array, n) {
  let arr = [];
  if (!Array.isArray(array)) {
    return [];
  } else if (isNaN(n) || n == null || n <= 0) {
    return [array[0]];
  } else {
    for (let i = 0; i < n && i < array.length; i++) {
      arr.push(array[i]);
    }
  }
  return arr;
};

I would be happy to get some guidance to understand why I am failing to pass the arguments object test. Thanks!

Edit: the solution to my problem:

function (array, n) {
  let arr = [];
  if (
    !(
      Array.isArray(array) ||
      Object.prototype.toString.call(array) === "[object Arguments]"
    )
  ) {
    return [];
  }
  if (isNaN(n) || n == null || n <= 0) {
    return [array[0]];
  } else {
    for (let i = 0; i < n && i < array.length; i++) {
      arr.push(array[i]);
    }
  }
  return arr;
};


Solution

  • The problem with your first function is in your base case wherein you're testing Array.isArray(). The args object is array-like and not array. So you've to factor in that case as well. You can check if the input is an instance of arguments. Something like:

    
    function isArrayLike(obj) {
      // Check if the input is an array or an arguments object
      return Array.isArray(obj) || Object.prototype.toString.call(obj) === '[object Arguments]';
    }
    
    _.first = function (array, n) {
      let arr = [];
      
      // Check if the input has a length property
      if (!isArrayLike(array)) {
        return [];
      }
    // ...rest
    };
    

    const _ = {};
    
    function isArrayLike(obj) {
      return Array.isArray(obj) || Object.prototype.toString.call(obj) === '[object Arguments]';
    }
    
    _.first = function(array, n) {
      let arr = [];
    
      if (!isArrayLike(array)) {
        return [];
      } else if (isNaN(n) || n == null || n <= 0) {
        return [array[0]];
      } else {
        for (let i = 0; i < n && i < array.length; i++) {
          arr.push(array[i]);
        }
      }
    
      return arr;
    };
    
    function testFirstWithArgs() {
      function testFunc() {
        const result = _.first(arguments, 2);
        return result;
      }
    
      const expected = [1, 2];
      const actual = testFunc(1, 2, 3, 4, 5);
    
      if (JSON.stringify(actual) === JSON.stringify(expected)) {
        console.log("PASS");
      } else {
        console.log("FAIL");
      }
    }
    
    testFirstWithArgs();