Home > Software design >  Getting "undefined" in my function in findMyCampsites()
Getting "undefined" in my function in findMyCampsites()

Time:09-08

This was the coding challenge:

Qualified challenge requirements:
Write a function findMyCampsites(). Given a campgrounds array, a type of view as a string, and the party size as a number, return an array with campsite numbers for the matching campsites. That is, your function should return results that match the following three criteria:

a. Currently available campsites (isReserved === false)
b. With the view that matches the input string (such as ocean or forest)
c. That can host the party size of the input number, or greater
If no sites are available, return the string Sorry, no campsites with that view are available to host your party

This is the sample Array given:

let campgrounds = [ 
    { number: 1, view: "ocean", partySize: 8, isReserved: false }, 
    { number: 5, view: "ocean", partySize: 4, isReserved: false }, 
    { number: 12, view: "ocean", partySize: 4, isReserved: true }, 
    { number: 18, view: "forest", partySize: 4, isReserved: false }, 
    { number: 23, view: "forest", partySize: 4, isReserved: true }, 
];

This is the example return given:

//example input/output 

findMyCampsites(campgrounds, "ocean", 4); //-> [1, 5] 
findMyCampsites(campgrounds, "ocean", 8); //-> [1] 
findMyCampsites(campgrounds, "forest", 4); //-> [18] 
findMyCampsites(campgrounds, "forest", 6); //-> 'Sorry, no campsites with that view are available to host your party'

This is my code:

function findMyCampsites(campgrounds, views, size){
  let array = [];
  for (let i = 0; i < campgrounds.length; i  ){
    for (let j = 0; j < campgrounds[i].view.length; j  ){
      for (let p = 0; p < campgrounds[i].partySize.length; p  ){
        for (let n = 0; n < campgrounds[i].number.length; n  ){
          if (campgrounds[i].view[j] === views && campgrounds[i].partySize[p] <= size && campgrounds[i].isReserved === false){
            return array.push(campgrounds[i].number[n])   ", ";
          }else {
            return "Sorry, no campsites with that view are available to host your party";
          } 
        }
      }
    }
  }
}

I'm getting undefined in as my return value. What did I do wrong?

CodePudding user response:

Try to steer clear of basic for loops and try using high-level idiomatic JS array methods which provide a much clearer conceptual framework for approaching array algorithms. In this case, we're filtering to find the campsites, then mapping those campsites to their ids--two loops, no nesting. If you are going to use bare loops, return only at the very end rather than after the first check.

Also, code like campgrounds[i].number.length and campgrounds[i].partySize.length doesn't make sense because these properties aren't arrays, they're plain numbers. To debug this, you'd normally print or inspect the property and see that it's undefined.

const campgrounds = [ { number: 1, view: "ocean", partySize: 8, isReserved: false, }, { number: 5, view: "ocean", partySize: 4, isReserved: false, }, { number: 12, view: "ocean", partySize: 4, isReserved: true, }, { number: 18, view: "forest", partySize: 4, isReserved: false, }, { number: 23, view: "forest", partySize: 4, isReserved: true, }, ];

const findMyCampsites = (campgrounds, view, partySize) => {
  const res = campgrounds.
    filter(e =>
      !e.isReserved &&
      e.view === view &&
      e.partySize >= partySize
    )
    .map(e => e.number);
  return res.length
    ? res
    : "Sorry, no campsites with that view are available to host your party";
};

console.log(findMyCampsites(campgrounds, "ocean", 4)); //-> [1, 5]
console.log(findMyCampsites(campgrounds, "ocean", 8)); //-> [1]
console.log(findMyCampsites(campgrounds, "forest", 4)); //-> [18]
console.log(findMyCampsites(campgrounds, "forest", 6)); //-> 'Sorry, no campsites

Here's the same thing without the array methods for pedagogical purposes only:

const findMyCampsites = (campgrounds, view, partySize) => {
  const res = [];
  
  for (let i = 0; i < campgrounds.length; i  ) {
    const e = campgrounds[i];

    if (
      !e.isReserved &&
      e.view === view &&
      e.partySize >= partySize
    ) {
      res.push(e.number);
    }
  }

  return res.length
    ? res
    : "Sorry, no campsites with that view are available to host your party";
};

The above code wouldn't be too bad if it used a for (const e of campgrounds) loop. The counters are ugly and error-prone, which the original code proves. When you use high-level iteration, you'll get a clear error trying to iterate non-iterables rather than a silent failure and there's no .length property to have to reason about.

Also, functions generally should only return a single type. Notwithstanding the task's requirements, it's better to return an empty array rather than a magical string "Sorry..." to indicate failure, which can lead to all kinds of maintainability issues (potential bug: assuming the return's .length === 0 means no campsites were found--the caller would have to do typeof result === "string" or compare it against the magic string all over again--not fun), mixing presentation and logic and creating typing nightmares in a codebase (number[] | string is a nasty signature to have to work with).

  • Related