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?

0
ampher911 16 avril 2018 à 04:59

5 réponses

Meilleure réponse

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);
};
1
Sam 16 avril 2018 à 05:06

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')
})
1
3stacks 16 avril 2018 à 02:10

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);
};
1
Ele 16 avril 2018 à 02:14

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))
1
JohanP 16 avril 2018 à 02:09

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)
1
Mark Meyer 16 avril 2018 à 02:25