Javascript 映射数组最后一项

我有这个:

map = ranks.map((row, r) => (
row.map((rank, i) => {
return [element(r, i, state, rank, toggled, onClick)];
})
));

它通过二维数组映射。 在每一行之后,我想插入 <div class="clearfix"></div>

我认为,如果我能以某种方式获得每一行的最后一个索引,那么我将能够在行映射回调中使用它。有人能教我怎么做吗?

150886 次浏览

Try something like:

row.map((rank, i, row) => {
if (i + 1 === row.length) {
// Last one.
} else {
// Not last one.
}
})

Old answer:

const rowLen = row.length;
row.map((rank, i) => {
if (rowLen === i + 1) {
// last one
} else {
// not last one
}
})

As LeoYuan answered, this is the correct answer, but it can be a bit improved.
map accepts a function with a third parameter, which is the iterated array itself.

row.map((rank, i, arr) => {
if (arr.length - 1 === i) {
// last one
} else {
// not last one
}
});

or in a bit shorter version, using an object destructuring (thanks Jose from the comments):

row.map((rank, i, {length}) => {
if (length - 1 === i) {
// last one
} else {
// not last one
}
});

Using an arr.length instead of row.length is a better and correct approach for several reasons:

  1. When you mix scopes, it may lead for an unexpected bugs, especially in a poorly written or poorly designed code. In general, it is always a good way to avoid mixing between scopes when possible.

  2. When you like to provide an explicit array, it will work as well. E.g.

    [1,2,3,4].map((rank, i, arr) => {
    if (arr.length - 1 === i) {
    // last one
    } else {
    // not last one
    }
    });
    
  3. If you like to move the callback outside of the map scope (mainly for a better performance), it will be wrong to use row.length as it is out of scope. E.g. in the OP case:

    const mapElement = (rowIndex, state, toggled, onClick) => {
    return (rank, i, arr) => {
    let lastIndex = arr.length - 1;
    return [element(rowIndex, i, state, rank, toggled, onClick, lastIndex)];
    };
    };
    
    
    map = ranks.map((row, r) => row.map(mapElement(r, state, toggled, onClick)));
    

A slight improvement on the accepted answer:

const lastIndex = row.length - 1;
row.map((rank, i) => {
if (i === lastIndex) {
// last one
} else {
// not last one
}
})

This removes the arithmetic from inside the loop.

you can check last index with your array's length. here is a logic

var randomnumber = Math.floor(Math.random() * (100 - 10 + 1)) + 10


console.log("your last index is dynamic, ehich is ",randomnumber-1);
let arry = [];
for (i=1;i<randomnumber;i++){
arry.push(i)
}


arry.map((data,index)=>{
if(index == arry.length-1 ){
console.log("last index data  ",data)
}
else{
console.log("remain data ",data)
          

}


})


console.log("your last index is dynamic, which is ",randomnumber-1);
this is also works in dynamic arry changes.. it is a too simple technique which i use .. :-)

const array = ['apple','orange','banana'];


array.map((element, index) => {
//Last element
if (index === array.length - 1) {
return `${element}.`;
}
//Another elements
return `${element}, `;
})}

Will return apple, orange, banana.

simplify answer above

const array = ['apple','orange','banana'];


array.map((element, index) => (index === array.length - 1) ? \`${element}.\` : \`${element},\`);

A shorter method would be to use .map combined with ternary operator, like this.

const positions = ["first", "second", "third", "fourth"]


positions.map((x, index, array) => {
index === array.length -1
? console.log("this is the last item in the array")
: console.log( x)
}

//////////// explanation

x ### returns the current element .map is looping through

index ### returns the index(location of item in an array) of the current element.

array ### return the same element we are looping through so if we use sth like this

 ["first", "second", "third", "fourth"].map...

we'll still get the array we're looping through

array.length - 1 ### gives us the length of the array and - 1 gives us the index of the last element in the array.

Fewer lines of code with the same results

row.map((rank, i, {length}) => (


//last element
if(i + 1 === length){


}
));

Perhaps the most concise way (although a little "dirty" – you can get some ESLint errors and TypeScript also might not be happy about that) to access the length property in array.map() is to pull it out (by destructuring) of the third callback argument (which is the array we are mapping over) and then assign a new property e. g. lastIndex, which value is being derived from that previously pulled out length:

let list = ["Alice", "Bob", "Cedrick", "David", "Emily"]


let mapped = list.map((item, i, {length, lastIndex = length - 1}) => {
return i === lastIndex ? "lastitem: " + item : item
})


console.log(mapped)