sort - javascript tutorial




Determina se un array contiene un valore (12)

Array.prototype.includes ()

In ES2016, c'è Array.prototype.includes() .

Il metodo includes() determina se un array include un determinato elemento, restituendo true o false seconda dei casi.

Esempio

["Sam", "Great", "Sample", "High"].includes("Sam"); // true

Supporto

Secondo kangax e MDN , sono supportate le seguenti piattaforme:

  • Chrome 47
  • Edge 14
  • Firefox 43
  • Opera 34
  • Safari 9
  • Nodo 6

Il supporto può essere espanso usando Babel (usando babel-polyfill ) o core-js . MDN fornisce anche un 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;
  };
}

Questa domanda ha già una risposta qui:

Devo determinare se esiste un valore in un array.

Sto usando la seguente funzione:

Array.prototype.contains = function(obj) {
    var i = this.length;
    while (i--) {
        if (this[i] == obj) {
            return true;
        }
    }
    return false;
}

La funzione sopra riportata restituisce sempre false.

I valori dell'array e la chiamata della funzione sono i seguenti:

arrValues = ["Sam","Great", "Sample", "High"]
alert(arrValues.contains("Sam"));

È quasi sempre più sicuro usare una libreria come lodash semplicemente a causa di tutti i problemi con compatibilità ed efficienza del browser.

Efficienza perché è possibile garantire che in qualsiasi momento una libreria estremamente popolare come il trattino basso avrà il metodo più efficiente per eseguire una funzione di utilità come questa.

_.includes([1, 2, 3], 3); // returns true

Se sei preoccupato per il grosso che viene aggiunto alla tua applicazione includendo l'intera libreria, sappi che puoi includere funzionalità separatamente:

var includes = require('lodash/collections/includes');

AVVISO: Con le versioni precedenti di lodash, questo era _.contains() piuttosto che _.includes() .


Data l'implementazione di indexOf per IE (come descritto da eyelidnessness):

Array.prototype.contains = function(obj) {
    return this.indexOf(obj) > -1;
};

Il mio piccolo contributo:

function isInArray(array, search)
{
    return array.indexOf(search) >= 0;
}

//usage
if(isInArray(my_array, "my_value"))
{
    //...
}

La risposta fornita non ha funzionato per me, ma mi ha dato un'idea:

Array.prototype.contains = function(obj)
    {
        return (this.join(',')).indexOf(obj) > -1;
    }

Non è perfetto perché gli oggetti che sono gli stessi oltre i raggruppamenti potrebbero finire con l'abbinamento. Come il mio esempio

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);
}

Quando chiamo questa funzione con i campi 'g' e 'h' che contengono rispettivamente 1 e 2, la trova ancora perché la stringa risultante dal join è: 1,1,2,2,3,3

Dal momento che è dubbio nella mia situazione che incontrerò questo tipo di situazione, sto usando questo. Ho pensato di condividere in caso che qualcun altro non potesse far funzionare la risposta scelta.


La soluzione più semplice per una funzione contains , sarebbe una funzione simile a questa:

var contains = function (haystack, needle) {
    return !!~haystack.indexOf(needle);
}

Idealmente, non si renderebbe comunque una funzione autonoma, ma parte di una libreria di supporto:

var helper = {};

helper.array = {
    contains : function (haystack, needle) {
        return !!~haystack.indexOf(needle);
    }, 
    ...
};

Ora, se ti capita di essere una di quelle persone sfortunate che hanno ancora bisogno di supportare IE <9 e quindi non può contare su indexOf , puoi usare questo polyfill , che ho ottenuto da 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;
  };
}

Puoi utilizzare il metodo _.indexOf o se non vuoi includere tutta la libreria Underscore.js nella tua app, puoi dare un'occhiata a come lo hanno fatto ed estrarre il codice necessario.

    _.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;
  };

Questo è generalmente il significato del metodo indexOf (). Tu diresti:

return arrValues.indexOf('Sam') > -1

Un'altra opzione sarebbe quella di utilizzare Array.some ( se disponibile ) nel modo seguente:

Array.prototype.contains = function(obj) {
  return this.some( function(e){ return e === obj } );
}

La funzione anonima passata ad Array.some restituirà true se e solo se c'è un elemento nell'array identico a obj . Assente un tale elemento, la funzione non restituirà true per nessuno degli elementi dell'array, quindi anche Array.some restituirà false .


Wow, ci sono molte ottime risposte a questa domanda.

Non ne ho visto uno che ha un approccio di reduce quindi lo aggiungerò in:

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);

Ecco un po 'di esso in azione .


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;
}

Esempio

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>

Risposta più lunga

So che questa domanda non riguarda in realtà se estendere o meno gli oggetti built-in, ma il tentativo dell'OP e i commenti su questa risposta evidenziano il dibattito. Il mio commento del 12 febbraio '13 cita un articolo che delinea molto bene questo dibattito, tuttavia quel link si è rotto e non posso modificare il commento originale perché è passato troppo tempo, quindi lo includo here .

Se stai cercando di estendere l'oggetto Array integrato con un metodo contains , probabilmente il modo migliore e più responsabile per farlo sarebbe utilizzare questo polyfill da Array.prototype.includes() . (Vedere anche this sezione dell'articolo MDN sull'ereditarietà del prototipo, che spiega che "L'unica buona ragione per estendere un prototipo incorporato è di eseguire il backport delle funzionalità dei nuovi motori JavaScript, ad esempio Array.forEach, ecc." )

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;
  };
}

Non vuoi l'uguaglianza rigorosa o vuoi scegliere?

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;
}

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;
}

Questo programma controlla se l'elemento dato è stato trovato o meno. Id testo1 rappresenta l'id della casella di testo e searchele rappresenta l'elemento da cercare (ottenuto dall'utente); se vuoi indice, usa il valore i





contains