Déterminer si un tableau contient une valeur [double]
-
19-09-2019 - |
Question
Cette question a déjà une réponse ici:
Je dois déterminer si une valeur existe dans un tableau.
J'utilise la fonction suivante:
Array.prototype.contains = function(obj) {
var i = this.length;
while (i--) {
if (this[i] == obj) {
return true;
}
}
return false;
}
La fonction ci-dessus renvoie toujours false.
Les valeurs de tableau et l'appel de fonction est comme ci-dessous:
arrValues = ["Sam","Great", "Sample", "High"]
alert(arrValues.contains("Sam"));
La solution
var contains = function(needle) {
// Per spec, the way to identify NaN is that it is not equal to itself
var findNaN = needle !== needle;
var indexOf;
if(!findNaN && typeof Array.prototype.indexOf === 'function') {
indexOf = Array.prototype.indexOf;
} else {
indexOf = function(needle) {
var i = -1, index = -1;
for(i = 0; i < this.length; i++) {
var item = this[i];
if((findNaN && item !== item) || item === needle) {
index = i;
break;
}
}
return index;
};
}
return indexOf.call(this, needle) > -1;
};
Vous pouvez l'utiliser comme ceci:
var myArray = [0,1,2],
needle = 1,
index = contains.call(myArray, needle); // true
Autres conseils
jQuery a une fonction d'utilité pour cela:
$.inArray(value, array)
Retourne l'index de value
dans array
. Retours -1
si array
ne contient pas value
.
Voir aussi Comment puis-je vérifier si un tableau comprend un objet en JavaScript?
Ceci est généralement ce que la méthode indexOf () est pour. Vous diriez:
return arrValues.indexOf('Sam') > -1
Array.prototype.includes ()
Dans ES2016, il est Array.prototype.includes()
.
La méthode de
includes()
détermine si un réseau comprend un certain élément, le retourtrue
oufalse
selon le cas.
Exemple
["Sam", "Great", "Sample", "High"].includes("Sam"); // true
Support
Selon kangax et noreferrer , les MDN sont pris en charge les plates-formes suivantes:
- Chrome 47
- Edge 14
- Firefox 43
- Opera 34
- Safari 9
- noeud 6
Le support peut être étendu en utilisant Babel (en utilisant babel-polyfill
) ou core-js
. Fournit également un MDN polyfill :
if (![].includes) {
Array.prototype.includes = function(searchElement /*, fromIndex*/ ) {
'use strict';
var O = Object(this);
var len = parseInt(O.length) || 0;
if (len === 0) {
return false;
}
var n = parseInt(arguments[1]) || 0;
var k;
if (n >= 0) {
k = n;
} else {
k = len + n;
if (k < 0) {k = 0;}
}
var currentElement;
while (k < len) {
currentElement = O[k];
if (searchElement === currentElement ||
(searchElement !== searchElement && currentElement !== currentElement)) {
return true;
}
k++;
}
return false;
};
}
Il est presque toujours plus sûr d'utiliser une bibliothèque comme lodash simplement à cause de tous les problèmes avec compatibilités multi-navigateurs et l'efficacité .
Efficacité parce que vous pouvez être assuré que, à tout moment, une bibliothèque très populaire comme underscore aura la méthode la plus efficace de réaliser une fonction d'utilité comme celui-ci.
_.includes([1, 2, 3], 3); // returns true
Si vous êtes préoccupé par la majorité qui est ajouté à votre demande en incluant l'ensemble, sachez que vous pouvez inclure des fonctionnalités séparément:
var includes = require('lodash/collections/includes');
AVIS: Avec les anciennes versions de lodash, cela a été _.contains()
plutôt que _.includes()
.
tl; dr
function includes(k) {
for(var i=0; i < this.length; i++){
if( this[i] === k || ( this[i] !== this[i] && k !== k ) ){
return true;
}
}
return false;
}
Exemple
function includes(k) {
for(var i=0; i < this.length; i++){
if( this[i] === k || ( this[i] !== this[i] && k !== k ) ){
return true;
}
}
return false;
}
function log(msg){
$('#out').append('<div>' + msg + '</div>');
}
var arr = [1, "2", NaN, true];
arr.includes = includes;
log('var arr = [1, "2", NaN, true];');
log('<br/>');
log('arr.includes(1): ' + arr.includes(1));
log('arr.includes(2): ' + arr.includes(2));
log('arr.includes("2"): ' + arr.includes("2"));
log('arr.includes(NaN): ' + arr.includes(NaN));
log('arr.includes(true): ' + arr.includes(true));
log('arr.includes(false): ' + arr.includes(false));
#out{
font-family:monospace;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id=out></div>
réponse plus longue
Je sais que cette question est vraiment de savoir si ou de ne pas prolonger objets intégrés, mais la tentative de l'OP et les commentaires sur cette réponse soulignent que le débat. Mon commentaire du 12 février '13 cite un article qui décrit ce débat très bien, mais ce lien cassé et je ne peux pas modifier le commentaire original parce que trop de temps a passé, donc je l'inclure ici .
Si vous cherchez à étendre l'objet Array
intégré avec une méthode de contains
, probablement le meilleur et le plus responsable de le faire serait d'utiliser cette polyfill MDN. (Voir aussi cette section de l'article sur prototypique MDN héritage, ce qui explique que « La seule bonne raison de l'extension d'un prototype intégré est de rétroporter les caractéristiques des moteurs JavaScript plus récents;. par exemple Array.forEach, etc » )
if (!Array.prototype.includes) {
Array.prototype.includes = function(searchElement /*, fromIndex*/ ) {
'use strict';
var O = Object(this);
var len = parseInt(O.length) || 0;
if (len === 0) {
return false;
}
var n = parseInt(arguments[1]) || 0;
var k;
if (n >= 0) {
k = n;
} else {
k = len + n;
if (k < 0) {k = 0;}
}
var currentElement;
while (k < len) {
currentElement = O[k];
if (searchElement === currentElement ||
(searchElement !== searchElement && currentElement !== currentElement)) {
return true;
}
k++;
}
return false;
};
}
Vous ne voulez pas une stricte égalité, ou si vous voulez choisir?
function includes(k, strict) {
strict = strict !== false; // default is true
// strict = !!strict; // default is false
for(var i=0; i < this.length; i++){
if( (this[i] === k && strict) ||
(this[i] == k && !strict) ||
(this[i] !== this[i] && k !== k)
) {
return true;
}
}
return false;
}
Depuis ECMAScript6, on peut utiliser Set
:
var myArray = ['A', 'B', 'C'];
var mySet = new Set(myArray);
var hasB = mySet.has('B'); // true
var hasZ = mySet.has('Z'); // false
Ma petite contribution:
function isInArray(array, search)
{
return array.indexOf(search) >= 0;
}
//usage
if(isInArray(my_array, "my_value"))
{
//...
}
Compte tenu de la mise en œuvre de indexOf pour IE (comme décrit par eyelidlessness):
Array.prototype.contains = function(obj) {
return this.indexOf(obj) > -1;
};
Si vous avez accès à ECMA 5, vous pouvez utiliser la méthode certains .
arrValues = ["Sam","Great", "Sample", "High"];
function namePresent(name){
return name === this.toString();
}
// Note:
// namePresent requires .toString() method to coerce primitive value
// i.e. String {0: "S", 1: "a", 2: "m", length: 3, [[PrimitiveValue]]: "Sam"}
// into
// "Sam"
arrValues.some(namePresent, 'Sam');
=> true;
Si vous avez accès à 6 ECMA vous pouvez utiliser le comprend la méthode .
arrValues = ["Sam","Great", "Sample", "High"];
arrValues.includes('Sam');
=> true;
Vous pouvez utiliser _.indexOf méthode ou si vous ne voulez pas inclure toute la bibliothèque Underscore.js dans votre application, vous pouvez avoir un comment ils ont fait et extraire le code nécessaire.
_.indexOf = function(array, item, isSorted) {
if (array == null) return -1;
var i = 0, l = array.length;
if (isSorted) {
if (typeof isSorted == 'number') {
i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
} else {
i = _.sortedIndex(array, item);
return array[i] === item ? i : -1;
}
}
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
for (; i < l; i++) if (array[i] === item) return i;
return -1;
};
Une autre option serait d'utiliser Wow, il y a beaucoup de bonnes réponses à cette question. Je n'ai pas vu celui qui prend en approche Array.some
(
reduce
donc je vais ajouter: var searchForValue = 'pig';
var valueIsInArray = ['horse', 'cat', 'dog'].reduce(function(previous, current){
return previous || searchForValue === current ? true : false;
}, false);
console.log('The value "' + searchForValue + '" is in the array: ' + valueIsInArray);
La réponse fournie ne fonctionne pas pour moi, mais il m'a donné une idée:
Array.prototype.contains = function(obj)
{
return (this.join(',')).indexOf(obj) > -1;
}
Il est pas parfait parce que les éléments qui sont les mêmes au-delà des regroupements pourraient finir par correspondance. Tels que mon exemple
var c=[];
var d=[];
function a()
{
var e = '1';
var f = '2';
c[0] = ['1','1'];
c[1] = ['2','2'];
c[2] = ['3','3'];
d[0] = [document.getElementById('g').value,document.getElementById('h').value];
document.getElementById('i').value = c.join(',');
document.getElementById('j').value = d.join(',');
document.getElementById('b').value = c.contains(d);
}
Quand j'appelle cette fonction avec le « g » et « h » champs contenant 1 et 2 respectivement, ce qu'il trouve encore parce que la chaîne résultant de la jointure est: 1,1,2,2,3,3
Comme il est douteux dans ma situation que je viendrai dans ce genre de situation, j'utilise cela. Je pensais que je partagerais Incase quelqu'un d'autre ne pouvait pas faire le travail soit de réponse choisie.
En utilisant la fonction de tableau qui exécute une fonction pour chaque valeur dans un tableau me semble propre à.
Cette méthode peut bien fonctionner aussi bien pour les tableaux simples et pour les tableaux d'objets où vous avez besoin pour voir si une clé / valeur existe dans un tableau d'objets.
function inArray(myArray,myValue){
var inArray = false;
myArray.map(function(key){
if (key === myValue){
inArray=true;
}
});
return inArray;
};
var anArray = [2,4,6,8]
console.log(inArray(anArray, 8)); // returns true
console.log(inArray(anArray, 1)); // returns false
function inArrayOfObjects(myArray,myValue,objElement){
var inArray = false;
myArray.map(function(arrayObj){
if (arrayObj[objElement] === myValue) {
inArray=true;
}
});
return inArray;
};
var objArray = [{id:4,value:'foo'},{id:5,value:'bar'}]
console.log(inArrayOfObjects(objArray, 4, 'id')); // returns true
console.log(inArrayOfObjects(objArray, 'bar', 'value')); // returns true
console.log(inArrayOfObjects(objArray, 1, 'id')); // returns false
function setFound(){
var l = arr.length, textBox1 = document.getElementById("text1");
for(var i=0; i<l;i++)
{
if(arr[i]==searchele){
textBox1 .value = "Found";
return;
}
}
textBox1 .value = "Not Found";
return;
}
Ce programme vérifie si l'élément donné est trouvé ou non. ça Text1 représente id de zone de texte et searchele représente élément à recherché (utilisateur a obtenu Fron); si vous voulez index, utilisez i Valeur
La solution la plus simple pour une fonction contains
, serait une fonction qui ressemble à ceci:
var contains = function (haystack, needle) {
return !!~haystack.indexOf(needle);
}
Idéalement, vous ne feriez pas cette fonction autonome, cependant, mais une partie d'une bibliothèque d'aide:
var helper = {};
helper.array = {
contains : function (haystack, needle) {
return !!~haystack.indexOf(needle);
},
...
};
Maintenant, si vous arrive d'être une de ces personnes malchanceux qui doit encore soutenir IE <9 et ne peut donc pas compter sur indexOf
, vous pouvez utiliser cette polyfill , que je suis de la MDN:
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(searchElement, fromIndex) {
var k;
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
var len = o.length >>> 0;
if (len === 0) {
return -1;
}
var n = +fromIndex || 0;
if (Math.abs(n) === Infinity) {
n = 0;
}
if (n >= len) {
return -1;
}
k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
while (k < len) {
if (k in o && o[k] === searchElement) {
return k;
}
k++;
}
return -1;
};
}
Je préfère la simplicité:
var days = [1, 2, 3, 4, 5];
if ( 2 in days ) {console.log('weekday');}