Je veux vérifier si ma variable est un tableau et si ses éléments contiennent des sous-chaînes avec '.png' ou '.jpg'. J'ai donc écrit ce code:
let test = ['empty_250x380@3x.png',
'empty_250x380@3x.png',
'empty_250x380@3x.png',
'empty_250x380@3x.png',
'empty_250x380@3x.png','empty_250x380@3x.png']
if(Array.isArray(test))
{
for(let n in test)
{
if(test[n].includes('.png') || test[n].includes('.PNG') || test[n].includes('.jpg') || test[n].includes('.JPG') )
{
test.splice(n,1);
}
}
console.log(test.length); // here is 3
};
Mais cela laisse toujours passer chaque index pair du tableau, donc je me trompe sur la moitié des scores. Je n'ai aucune idée de comment c'est même possible. Savez-vous comment puis-je le réparer?
5 réponses
Le problème avec l'itération est que l'index va de 0 to 5
tout en splice
ing tableau. Lorsque l'index atteint le 3ème élément, la taille du tableau devient 3
et donc test[3]
, test[4]
et test[5]
n'est pas définie. C'est pourquoi vous obtenez la taille 3
. Essayez d'itérer de 5
à 0
, par exemple:
let test = ['empty_250x380@3x.png', 'empty_250x380@3x.png', 'empty_250x380@3x.png', 'empty_250x380@3x.png', 'empty_250x380@3x.png', 'empty_250x380@3x.png'];
if(Array.isArray(test)) {
for(let n = test.length - 1; n >= 0; n--) {
if(test[n].includes('.png') || test[n].includes('.PNG') || test[n].includes('.jpg') || test[n].includes('.JPG')) {
test.splice(n, 1);
}
}
console.log(test.length);
};
Alternativement, vous pouvez utiliser l'expression régulière pour réduire votre code:
let test = ['empty_250x380@3x.png', 'empty_250x380@3x.png', 'empty_250x380@3x.png', 'empty_250x380@3x.png', 'empty_250x380@3x.png', 'empty_250x380@3x.png'];
if(Array.isArray(test)) {
for(let n = test.length - 1; n >= 0; n--) {
if(/\.(png|jpg)$/i.test(test[n])) {
test.splice(n, 1);
}
}
console.log(test.length);
};
Une meilleure version:
let test = ['empty_250x380@3x.png', 'empty_250x380@3x.png', 'empty_250x380@3x.png', 'empty_250x380@3x.png', 'empty_250x380@3x.png', 'empty_250x380@3x.png'];
if(Array.isArray(test)) {
console.log(test.filter(e => ! /\.(png|jpg|svg)$/i.test(e)).length);
};
Vous pourriez avoir plus de succès en utilisant certaines des belles méthodes de tableau. Pour cela, vous utiliseriez un filtre pour supprimer les éléments dont vous ne voulez pas. En prime, il est immuable, il renvoie donc un nouveau tableau avec uniquement les éléments que vous souhaitez. Il semble également beaucoup mieux à mon avis.
const acceptableItems = test.filter(filename => {
// keep the item in the array if it includes png
return filename.includes('png') ...
// OR. remove it from the new array if it includes png
return !filename.includes('png')
})
Cette approche modifie le tableau actuel, ce qui entraîne une erreur concernant l'index actuel.
Une alternative consiste à exécuter une boucle inverse, car le problème principal est les index visités:
let test = ['empty_250x380@3x.png', 'empty_250x380@3x.png', 'empty_250x380@3x.png', 'empty_250x380@3x.png', 'empty_250x380@3x.png', 'empty_250x380@3x.png'];
if (Array.isArray(test)) {
var n = test.length;
while (n--) {
if (test[n].includes('.png') || test[n].includes('.PNG') || test[n].includes('.jpg') || test[n].includes('.JPG')) {
test.splice(n, 1);
console.log(test);
}
}
console.log(test.length); // here is 3
};
Recommandation: Obtenez l'extension de chaque image et utilisez la fonction Array.prototype.includes
let test = ['empty_250x380@3x.png', 'empty_250x380@3x.png', 'empty_250x380@3x.png', 'empty_250x380@3x.png', 'empty_250x380@3x.png', 'empty_250x380@3x.png'],
allowedExts = ['.png', '.jpg'];
if (Array.isArray(test)) {
var n = test.length;
while (n--) {
var ext = test[n].substring(test[n].lastIndexOf('.')).toLowerCase();
if (allowedExts.includes(ext)) test.splice(n, 1);
}
console.log(test.length);
};
Ce que vous pouvez faire, vérifiez si Array.isArray
, puis assurez-vous que l'élément every
de array
se termine par .png
ou. jpg
let test = ['empty_250x380@3x.png',
'empty_250x380@3x.png',
'empty_250x380@3x.png',
'empty_250x380@3x.jpg',
'empty_250x380@3x.png','empty_250x380@3x.png']
function check(arr) {
return Array.isArray(arr) && arr.every(i=>['.jpg','.png'].indexOf(i.slice(-4))!== - 1)
}
console.log(check(test))
Cela semble être un bon cas d'utilisation pour une expression régulière simple et every()
. L'expression régulière permet au test de s'ancrer à la fin de la ligne afin qu'il ne corresponde pas à un cas comme 'empty.pngstuff.txt', auquel includes()
correspondra. Et c'est très lisible.
let test_array = ['empty_250x380@3x.png',
'empty_250x380@3x.png',
'empty_250x380@3x.PNG',
'empty_250x380@3x.jpeg',
'pngempty_250x380@3x.png','empty_250x380@3x.png'
]
// i modifier makes it case insensitive
let re = RegExp(/.(png|jpeg)$/i)
let result = Array.isArray(test_array)
&& test_array.every(i => re.test(i))
console.log(result)
Questions connexes
De nouvelles questions
javascript
Pour des questions concernant la programmation dans ECMAScript (JavaScript / JS) et ses divers dialectes / implémentations (hors ActionScript). Veuillez inclure toutes les balises pertinentes dans votre question; par exemple, [node.js], [jquery], [json], etc.