Arguments object not working on Underscore first type function

54 Views Asked by At

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:

  • should return an array with the first n elements of the array
  • should return an array with the first element if n is not a number, is zero, or negative
  • should return the entire array if n is > length
  • should return an empty array if array is not an array

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;
};

1

There are 1 best solutions below

3
mandy8055 On BEST ANSWER

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();