1

I guys, I have a nested for loop but I want to do it with an Array map/ES6 way but how does that work with nested forloops?

        for (var i = 0; i < enemy.ships.length; i++) {
        for (var n = 0; n < enemy.ships[i].location.length; n++) {
            if (obj.coordination == enemy.ships[i].location[n]) hit = true;
        }
    };

I know how to do it when it as not a forloop

players.map(function(player){if(player.id != socket.id) return enemy = player});

But I can't seem to understand how it should be with Array Maps or something else.

I need to match the location of the ships location & obj.coordination. This is the enemy.ships variable I need to check

    [ { type: 'Aircaft',
    size: 5,
    rekt: false,
    available: 1,
    location: [] },
  { type: 'Battleship',
    size: 4,
    rekt: false,
    available: 1,
    location: [ 77, 76, 75, 74 ] },
  { type: 'Destroyer',
    size: 3,
    rekt: false,
    available: 2,
    location: [ 54, 44, 34 ] },
  { type: 'Submarine',
    size: 3,
    rekt: false,
    available: 3,
    location: [] },
  { type: 'Patrolboat',
    size: 2,
    rekt: false,
    available: 4,
    location: [] } ]
3
  • 1
    Use a nested forEach loop Commented Apr 3, 2016 at 21:28
  • You should add a sample of the data you're working with. Commented Apr 3, 2016 at 21:29
  • Just put the example of the data Commented Apr 3, 2016 at 22:05

3 Answers 3

4

If all you are looking for is whether any location on any ship matches (and not returning the ship that was hit, et cetera), you can use something like:

const hit = enemy.ships
  .map(ship => ship.location)
  .some(coordinates => coordinates.some(coordinate => coordinate === obj.coordination ));

If you wanted to return the ship that was hit (or the ships, if multiple ships were allowed to share the same coordinates):

const hitShips = enemy.ships
  .filter(ship => ship.location.some( coordinate => coordinate === obj.coordination ));

Your example of map is also a little... off.

The goal of map isn't to cause side-effects (in fact, it's specifically meant to avoid all side-effects).
The goal of map is to take one array of objects and return a brand new array of the exact same length, where you have filled the new array based on the objects of the old array.

[1, 2, 3].map( x => x + 1 ); // [2, 3, 4]
["a", "b", "c"].map( x => x.toUpperCase() ); // ["A", "B", "C"]

If you just want to check each item and cause side-effects (change a value that exists outside of the function passed in) then use forEach.

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

1 Comment

Thankyou ! This worked & thanks for the explaination.
3

You could use the forEach method to do it in a more functional way. However you won't be able to break from it once the location matches. Additional ref: how to stop Javascript forEach?

enemy.ships.forEach((ship) => {
    ship.location.forEach((location) => {
        if (obj.coordination === location)
            hit = true;
    })
})

3 Comments

As mentioned in the link posted by André, if you just want to check if the ship was hit you should use every(). Reference: developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/…
@AlexandreJunges you mean Array#some(). not every().
Yeah, that's right. some() is the right option for this case :)
0

You could use Array.prototype.find and filter:

For example:

var compareLocation = (a, b) => a.length === b.length && a.filter((v, i) => v === b[i]).length === a.length;
var enemyShipFound = enemy.ships.find(ship => compareLocation(obj.coordination, ship.location));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.