15

Create a function that takes an array of people objects and returns the first found astronaut object from the array.

This is the code that I have created;

function findFirstAstronaut(people) {
    for (let i = 0; i < people.length; i++) {
        if (people.astronaut[i] === false) {
            return null
        }
        else  if (people.astronaut[i]) {
            return people[i]
        }
    }

My code is run against this test;

describe("findFirstAstronaut", () => {
  it("returns null if no Astronaut is in the array", () => {
    expect(findFirstAstronaut([])).to.be.null;
  });

  it("returns a person object who is an astronaut", () => {
    const astronaut = { name: "Tim Peake", isAstronaut: true };
     expect(findFirstAstronaut([astronaut])).to.have.keys([
      "name",
      "isAstronaut"
    ]);
    expect(findFirstAstronaut([astronaut]).isAstronaut).to.be.true;
  });

  it("returns the first astronaut from the array", () => {
    const astronauts = [
      { name: "Johnny Karate", isAstronaut: false },
      { name: "Neil Armstrong", isAstronaut: true },
      { name: "Valentina Tereshkova", isAstronaut: true },
      { name: "Bert Macklin", isAstronaut: false },
      { name: "Eileen Collins", isAstronaut: true },
      { name: "Kip Hackman", isAstronaut: false }
    ];
    expect(findFirstAstronaut(astronauts)).to.eql({
      name: "Neil Armstrong",
      isAstronaut: true
    });
  });
});

How do I fix my code?

1
  • Is that a particular unit test framework? Commented Dec 24, 2018 at 23:36

5 Answers 5

11

ES6 introduces a new way to achieve this, if ES6 is an option for you:

myArray.find(item => {
  return item.isAstronaut
})

Or even more abbreviated:

myArray.find(item => item.isAstronaut)

find() is a one of the new iterators, along with filter() and map() and others for more easily working with arrays. find() will return the first item in your array that matches the condition. The => or "arrow function" means that you do not need to explicitly include the return statement.

Read more about ES6 iterators.

Sign up to request clarification or add additional context in comments.

Comments

5

You need to use the index for the array.

people[i]                // for the object
people[i].isAstronaut    // for a property of the object

Then you need only a check if isAstronaut is true and return with the item.

At the end outside of the for loop, return null, for a not found astronaut.

If you check inside the loop, you will return too early with the wrong result.

function findFirstAstronaut(people) {
    for (let i = 0; i < people.length; i++) {
        if (people[i].isAstronaut) {
            return people[i];
        }
    }
    return null;
}

Comments

5

One liner

arr.filter(item => item.isAstronaut)[0]

4 Comments

Is this lazy or does it iterate through the entire array?
It iterates through the whole array and which ever elements passes the condition are pushed into new array and the new array is returned.
Thing is, if only the first element is needed, constructing that whole new array is slower than returning as soon as the first element is found.
You are right. Find should be uaed instead. But find is relatively new. Some browsers dont have support for that. If thats not an issue you can use find.
1

You could simply filter out array elements that have an isAstronaut property equal to false using Array.prototype.filter. I prefer filter to Array.prototype.find since ES6 isn't supported in every browser.

Once you have the filtered array simply take the element in the 0 index position. Something like below:

const astronauts = [{
    name: "Johnny Karate",
    isAstronaut: false
  },
  {
    name: "Neil Armstrong",
    isAstronaut: true
  },
  {
    name: "Valentina Tereshkova",
    isAstronaut: true
  },
  {
    name: "Bert Macklin",
    isAstronaut: false
  },
  {
    name: "Eileen Collins",
    isAstronaut: true
  },
  {
    name: "Kip Hackman",
    isAstronaut: false
  }
];

//Array destructuring to get the first astronaut:
var [firstAstronautFound] = astronauts.filter(el => el.isAstronaut);

//Line above is same as doing this:
//var firstAstronautFound = astronauts.filter(el => el.isAstronaut)[0];

console.log(firstAstronautFound.name);

Comments

0

First, you may need to check whether there is any item in array or else return null.

Second, you have to check for the property

Third, you have to check for the value of the property isAstronaut

function findFirstAstronaut(people) {
   if (people.length > 0)
    {
      for (let i = 0; i < people.length; i++) {
         if (("name" in people[i]) && ("isAstronaut" in people[i])) {
           if (people[i].isAstronaut)
              return people[i];              
           else  
              return true;
       }
      }
     }
    else
      return null;
   }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.