Question

Je voudrais filtrer un tableau d'éléments à l'aide de la map() fonction.Voici un extrait de code:

var filteredItems = items.map(function(item)
{
    if( ...some condition... )
    {
        return item;
    }
});

Le problème est que filtrés articles encore utilise de l'espace dans le tableau et je voudrais complètement anéantir.

Une idée?

EDIT:Merci, je l'avais oublié filter(), ce que je voulais est en fait un filter() puis un map().

EDIT2:Merci pour cette map() et filter() ne sont pas mis en œuvre dans tous les navigateurs, même si mon code n'est pas destiné à s'exécuter dans un navigateur.

Était-ce utile?

La solution

Vous devez utiliser le filter méthode plutôt que de la carte, sauf si vous souhaitez muter les éléments du tableau, en plus du filtrage.

par exemple.

var filteredItems = items.filter(function(item)
{
    return ...some condition...;
});

[Edit:Bien sûr, vous pourriez faire sourceArray.filter(...).map(...) pour le filtre et de le faire muter]

Autres conseils

J'ai écrit une réponse à un certain temps en arrière maintenant, et mon avis a changé.Je recommande de vérifier mon post de blog qui développe ce sujet et explique beaucoup mieux.Il donne également une JSperf comparaison à la fin de la solutions de rechange.

Le tl;dr est ceci:Pour accomplir ce que vous me demandez (filtrage et de la cartographie dans un délai d'un appel de fonction), vous devez utiliser Array.reduce().Cependant, l' plus lisible et généralement plus rapide2 l'approche est d'utiliser le filtre et la carte enchaînés:

[1,2,3].filter(num => num > 2).map(num => num * 2)

Ce qui suit est une description de la façon dont Array.reduce() fonctionne, et comment il peut être utilisé pour accomplir le filtre et la carte en une seule itération.Si c'est trop condensé, je vous recommande fortement de voir le post de blog ci-dessus, qui est beaucoup plus facile d'intro avec des exemples clairs et de la progression.

Vous donnez réduire un argument qui est un (généralement anonymes) de la fonction.

Cette fonction anonyme prend deux paramètres: une (comme la fonction anonyme transmise à la carte/filtre/forEach) est l'iteratee à être exploité.Il est un autre argument pour la fonction anonyme transmise à réduire, cependant, que ces fonctions ne les acceptez pas, et qui est la valeur qui sera transmise entre les appels de fonction, souvent désigné comme le mémo.

Notez que lors de la Matrice.filtre() prend un seul argument (une fonction), Array.réduire() prend également un important (bien que facultatif) deuxième argument:une valeur initiale pour les "mémo" qui sera passé dans cette fonction anonyme comme premier argument, et par la suite peut être muté et transmis entre les appels de fonction.(Si elle n'est pas fournie, puis "memo" dans le premier anonyme appel de fonction, par défaut, être le premier iteratee, et le " iteratee l'argument sera effectivement la deuxième valeur dans le tableau)

Dans notre cas, nous allons passer dans un tableau vide pour commencer, et ensuite décider d'injecter notre iteratee dans notre tableau ou non en fonction de notre fonction--c'est le processus de filtrage.

Enfin, nous allons revenir à notre "tableau en cours" sur chaque anonymes appel de fonction, et de réduire prendront la valeur de retour et passer comme un argument (appelé bloc-notes) pour son prochain appel de la fonction.

Cela permet de filtrer et de la carte d'arriver dans une itération, en réduisant notre nombre d'itérations nécessaires à la moitié.:)

Pour une explication plus complète, reportez-vous à MDN ou sur le lien ci-dessus.:)

Exemple de base d'un appel:

let array = [1,2,3];
const initialMemo = [];

array = array.reduce((memo, iteratee) => {
    // if condition is our filter
    if (iteratee > 1) {
        // what happens inside the filter is the map
        memo.push(iteratee * 2); 
    }

    // this return value will be passed in as the 'memo' argument
    // to the next call of this function, and this function will have
    // every element passed into it at some point.
    return memo; 
}, initialMemo)

console.log(array) // [4,6], equivalent to [(2 * 2), (3 * 2)]

plus version succincte:

[1,2,3].reduce((memo, value) => value > 1 ? memo.concat(value * 2) : memo, [])

Notez que la première iteratee est pas supérieur à un, et donc a été filtré.Notez également la initialMemo, nommé juste pour faire de son existence clair et attirer l'attention sur elle.Encore une fois, il est passé en tant que 'memo' pour la première anonymes appel de la fonction, puis la valeur renvoyée de la fonction anonyme est transmis en tant que 'memo' argument à la fonction suivante.

Un autre exemple de l'utilisation classique de cas pour la note serait de retour le plus petit ou le plus grand nombre dans un tableau.Exemple:

[7,4,1,99,57,2,1,100].reduce((memo, val) => memo > val ? memo : val)
// ^this would return the largest number in the list.

Un exemple de la façon d'écrire votre propre fonction de réduction (ce qui permet souvent de comprendre ces fonctions, je trouve):

test_arr = [];

// we accept an anonymous function, and an optional 'initial memo' value.
test_arr.my_reducer = function(reduceFunc, initialMemo) {
    // if we did not pass in a second argument, then our first memo value 
    // will be whatever is in index zero. (Otherwise, it will 
    // be that second argument.)
    const initialMemoIsIndexZero = arguments.length < 2;

    // here we use that logic to set the memo value accordingly.
    let memo = initialMemoIsIndexZero ? this[0] : initialMemo;

    // here we use that same boolean to decide whether the first
    // value we pass in as iteratee is either the first or second
    // element
    const initialIteratee = initialMemoIsIndexZero ? 1 : 0;

    for (var i = initialIteratee; i < this.length; i++) {
        // memo is either the argument passed in above, or the 
        // first item in the list. initialIteratee is either the
        // first item in the list, or the second item in the list.
        memo = reduceFunc(memo, this[i]);
    }

    // after we've compressed the array into a single value,
    // we return it.
    return memo;
}

La mise en œuvre réelle permet d'accéder à des choses comme l'index, par exemple, mais j'espère que cela vous aide à obtenir une simple sensation pour l'essentiel.

Ce n'est pas ce que la carte ne.Vous voulez vraiment Tableau.filtre.Ou si vous voulez vraiment supprimer les éléments de la liste initiale, vous allez avoir besoin de le faire impérativement avec une boucle for.

Vous devez, toutefois, de noter que l' Array.filter n'est pas pris en charge dans tous les navigateurs, vous devez à un prototype:

//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.filter)
{
    Array.prototype.filter = function(fun /*, thisp*/)
    {
        var len = this.length;

        if (typeof fun != "function")
            throw new TypeError();

        var res = new Array();
        var thisp = arguments[1];

        for (var i = 0; i < len; i++)
        {
            if (i in this)
            {
                var val = this[i]; // in case fun mutates this

                if (fun.call(thisp, val, i, this))
                   res.push(val);
            }
        }

        return res;
    };
}

Et ce faisant, vous pouvez prototype de la méthode, vous pourriez avoir besoin.

Je suis en plaçant cette réponse ici, car les polyfills partagé sur cette page sont épouvantables

function reduce(f, y, xs, context) {
  var acc = y;
  for (var i = 0, len = xs.length; i < len; i++)
    acc = f.call(context, acc, xs[i], i, xs);
  return acc;
}

function reduce1(f, xs, context) {
  if (xs.length === 0)
    throw Error('cannot reduce empty array without initial value');
  else
    return reduce(f, xs[0], xs.slice(1), context);
}

function map(f, xs, context) {
  return reduce(function(acc, x, i) {
    return acc.concat([
      f.call(context, x, i, xs)
    ]);
  }, [], xs);
}

function filter(f, xs, context) {
  return reduce(function(acc, x, i) {
    if (f.call(context, x, i, xs))
      return acc.concat([x]);
    else
      return acc;
  }, [], xs);
}

étendre prototypes

if (Array.prototype.reduce === undefined) {
  Array.prototype.reduce = function(f, initialValue, context) {
    if (initialValue === undefined)
      return reduce1(f, this, context);
    else
      return reduce(f, initialValue, this, context);
  };
}

if (Array.prototype.map === undefined) {
  Array.prototype.map = function(f, context) {
    return map(f, this, context);
  };
}

if (Array.prototype.filter === undefined) {
  Array.prototype.filter = function(f, context) {
    return filter(f, this, context);
  };
}
var arr = [1,2,'xxx','yyy']

arr = arr.filter(function(e){ return e != 'xxx' });

arr  // [1, 2, "yyy"]
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top