0
votes

Comment filtrer un tableau JavaScript à l'aide de la méthode array.filter ()?

J'ai un objet JavaScript ( filtres ), qui a des valeurs booléennes. J'ai aussi un tableau d'objets ( mainSubArray ). Sur la base de l ' objet JavaScript, je souhaite retourner un nouveau tableau ( filteredArray ) si les valeurs booléennes sont vraies et ne pas renvoyer un nouveau tableau si la valeur booléenne est fausse. p> Jusqu'à présent, j'ai essayé ce qui suit:

// The main array that needs to be filtered
const mainSubArray = [{
    MenB_Classification: "NOT Required",
    CONTROL: "Public",
    Enrollment: "892"
  },
  {
    MenB_Classification: "Required",
    CONTROL: "Private",
    Enrollment: "1601"
  },
  {
    MenB_Classification: "NOT Required",
    CONTROL: "Private",
    Enrollment: "447"
  },
  {
    MenB_Classification: "NOT Required",
    CONTROL: "Public",
    Enrollment: "1203"
  },
  {
    MenB_Classification: "Required",
    CONTROL: "Private",
    Enrollment: "32"
  },
  {
    MenB_Classification: "NOT Required",
    CONTROL: "Public",
    Enrollment: "98"
  },
  {
    MenB_Classification: "Recommended",
    CONTROL: "Private",
    Enrollment: "654"
  },
  {
    MenB_Classification: "NOT Required",
    CONTROL: "Private",
    Enrollment: "345318"
  },
  {
    MenB_Classification: "NOT Required",
    CONTROL: "Private",
    Enrollment: "13324"
  },
  {
    MenB_Classification: "Recommended",
    CONTROL: "Private",
    Enrollment: "39"
  },
  {
    MenB_Classification: "NOT Required",
    CONTROL: "Private",
    Enrollment: "4"
  },
  {
    MenB_Classification: "NOT Required",
    CONTROL: "Private",
    Enrollment: "910"
  },
  {
    MenB_Classification: "NOT Required",
    CONTROL: "Private",
    Enrollment: "23453"
  }
]


// Object with boolean values
var filters = {
  required: true,
  recomended: true,
  notRequired: false,
  publics: true,
  privates: true,
  ennrollmentOne: true,
  ennrollmentTwo: false,
  ennrollmentThree: false,
  ennrollmentFour: false,
}

// New Array using array.filter() method
var filteredArray = mainSubArray.filter(function(d) {
  if ((filters.required == true && d.MenB_Classification === 'Required') || (filters.recomended === true && d.MenB_Classification === 'Recommended') || (filters.notRequired === true && d.MenB_Classification === 'NOT Required') || (filters.publics === true && d.CONTROL === 'Public') || (filters.privates === true && d.CONTROL === 'Private') || (filters.ennrollmentOne === true && d.Enrollment < 100) || (filters.ennrollmentTwo === true && d.Enrollment >= 100 && d.Enrollment < 1000) || (filters.ennrollmentThree === true && d.Enrollment >= 1000 && d.Enrollment < 5000) || (filters.ennrollmentThree === true && d.Enrollment > 5000)) {
    return true;
  } else {
    return false;
  }

});

console.log(filteredArray);

Quand je console.log (filteredArray) , je récupère le tableau d'origine.

La sortie doit être un nouveau tableau qui n'a que les valeurs qui sont définis sur true dans l'objet filters .


9 commentaires

J'ai essayé votre code et il semble que le tableau original mainSubArray a 13 éléments, le tableau filtré filteredArray a 12 éléments à l'intérieur, la différence est {MenB_Classification: "NOT Required", CONTROL: "33033764030", Enrollment: "345318"}


que font les filtres ? pourquoi n'a-t-il pas de valeurs directement comparables aux valeurs de l'objet?


À quoi voulez-vous que le tableau filtré ressemble? À l'heure actuelle, je pense que le problème vient de votre logique, puisque vous utilisez 9 ou 10 déclarations ou différentes, il correspond presque toujours à l'une d'entre elles. Je suggérerais également d'écrire someBoolean && au lieu de someBoolean === true && .


Votre condition if à l'intérieur de la fonction de filtre couvre tout et c'est pourquoi vous voyez le tableau d'origine comme résultat du filtre


Donc, si N'IMPORTE QUEL des filtres est vrai, incluez l'élément!? Ou devrait-il inclure uniquement les éléments auxquels tous les filtres s'appliquent?


Votre code semble correct, vu que la plupart des enregistrements ont des paramètres public et privé , et votre filtre demande les deux thèses, il est logique que cela règle seule va pratiquement retourner tous les enregistrements.


@Thomas Je suppose qu'un seul enregistrement ne peut pas être à la fois public et privé , donc cela ne semble pas être le cas. Le PO a vraiment besoin d'expliquer plus en détail pourquoi il pense que c'est faux, car dans l'état actuel des choses, cela semble parfaitement bien.


@NinaScholz le filtres est un objet qui est généré dynamiquement en fonction des cases à cocher. Si la case est cochée (ou active), la valeur correspondante est définie sur true.


@Maria, le tableau filtré devrait essentiellement être un nouveau tableau dérivé du tableau principal. La chose que j'essaie de réaliser est de sauter l'élément courant si la valeur de l'objet filtre est "false".


4 Réponses :


1
votes

Cela fonctionne, mais vos conditions couvrent presque tous les cas.

Même dans votre cas, cela fonctionne car le résultat contient 12 éléments au lieu de 13. Il ne contient pas:

{
    MenB_Classification: "NOT Required",
    CONTROL: "33033764030",
    Enrollment: "345318"
  },


1 commentaires

C'est juste la confirmation que le problème n'existe pas. La solution initiale fonctionne bien. L'autre code est juste pour le rendre plus élégant



-1
votes

Non, le filteredArray n'est pas le même que le tableau principal. Vous pouvez enregistrer la longueur pour sentir facilement la différence.

De plus, sinon peut être évité d'utiliser un retour sur toutes les conditions uniquement.

// The main array that needs to be filtered
const mainSubArray = [{
    MenB_Classification: "NOT Required",
    CONTROL: "Public",
    Enrollment: "892"
  },
  {
    MenB_Classification: "Required",
    CONTROL: "Private",
    Enrollment: "1601"
  },
  {
    MenB_Classification: "NOT Required",
    CONTROL: "Private",
    Enrollment: "447"
  },
  {
    MenB_Classification: "NOT Required",
    CONTROL: "Public",
    Enrollment: "1203"
  },
  {
    MenB_Classification: "Required",
    CONTROL: "Private",
    Enrollment: "32"
  },
  {
    MenB_Classification: "NOT Required",
    CONTROL: "Public",
    Enrollment: "98"
  },
  {
    MenB_Classification: "Recommended",
    CONTROL: "Private",
    Enrollment: "654"
  },
  {
    MenB_Classification: "NOT Required",
    CONTROL: "33033764030",
    Enrollment: "345318"
  },
  {
    MenB_Classification: "NOT Required",
    CONTROL: "Private",
    Enrollment: "13324"
  },
  {
    MenB_Classification: "Recommended",
    CONTROL: "Private",
    Enrollment: "39"
  },
  {
    MenB_Classification: "NOT Required",
    CONTROL: "Private",
    Enrollment: "4"
  },
  {
    MenB_Classification: "NOT Required",
    CONTROL: "Private",
    Enrollment: "910"
  },
  {
    MenB_Classification: "NOT Required",
    CONTROL: "Private",
    Enrollment: "23453"
  }
]


// Object with boolean values
var filters = {
  required: true,
  recomended: true,
  notRequired: false,
  publics: true,
  privates: true,
  ennrollmentOne: true,
  ennrollmentTwo: false,
  ennrollmentThree: false,
  ennrollmentFour: false,
}

// New Array using array.filter() method
var filteredArray = mainSubArray.filter(function(d) {
  return ((filters.required && d.MenB_Classification === 'Required') || (filters.recomended && d.MenB_Classification === 'Recommended') || (filters.notRequired && d.MenB_Classification === 'NOT Required') || (filters.publics && d.CONTROL === 'Public') || (filters.privates && d.CONTROL === 'Private') || (filters.ennrollmentOne && d.Enrollment < 100) || (filters.ennrollmentTwo && d.Enrollment >= 100 && d.Enrollment < 1000) || (filters.ennrollmentThree && d.Enrollment >= 1000 && d.Enrollment < 5000) || (filters.ennrollmentThree && d.Enrollment > 5000));
});
console.log(mainSubArray.length)
console.log(filteredArray.length);


1 commentaires

@TylerRoper Hé mec, ce n'était pas un problème mais plutôt une confusion. La suggestion de longueurs de journalisation sur la console est une solution pour supprimer sa confusion. :)



2
votes

Vous pouvez prendre un tableau de chaînes pour les clés de l'objet filtre et la fonction correspondante pour vérifier les clés voulues de l'objet avec leur / s valeur / s voulue.

Dans la fonction de filtrage, itérer le tableau des fonctions clés et quitter tôt si une fonction est recherchée et le résultat est true.

Le résultat est un tableau de 12 objets à partir de 13 objets originaux.

.as-console-wrapper { max-height: 100% !important; top: 0; }
var data = [{ MenB_Classification: "NOT Required", CONTROL: "Public", Enrollment: "892" }, { MenB_Classification: "Required", CONTROL: "Private", Enrollment: "1601" }, { MenB_Classification: "NOT Required", CONTROL: "Private", Enrollment: "447" }, { MenB_Classification: "NOT Required", CONTROL: "Public", Enrollment: "1203" }, { MenB_Classification: "Required", CONTROL: "Private", Enrollment: "32" }, { MenB_Classification: "NOT Required", CONTROL: "Public", Enrollment: "98" }, { MenB_Classification: "Recommended", CONTROL: "Private", Enrollment: "654" }, { MenB_Classification: "NOT Required", CONTROL: "33033764030", Enrollment: "345318" }, { MenB_Classification: "NOT Required", CONTROL: "Private", Enrollment: "13324" }, { MenB_Classification: "Recommended", CONTROL: "Private", Enrollment: "39" }, { MenB_Classification: "NOT Required", CONTROL: "Private", Enrollment: "4" }, { MenB_Classification: "NOT Required", CONTROL: "Private", Enrollment: "910" }, { MenB_Classification: "NOT Required", CONTROL: "Private", Enrollment: "23453" }],
    filters = {
        required: true,
        recomended: true,
        notRequired: false,
        publics: true,
        privates: true,
        ennrollmentOne: true,
        ennrollmentTwo: false,
        ennrollmentThree: false,
        ennrollmentFour: false,
    },
    fn = [
        ['required', o => o.MenB_Classification === 'Required'],
        ['recomended', o => o.MenB_Classification === 'Recommended'],
        ['notRequired', o => o.MenB_Classification === 'NOT Required'],
        ['publics', o => o.CONTROL === 'Public'],
        ['privates', o => o.CONTROL === 'Private'],
        ['ennrollmentOne', o => o.Enrollment < 100],
        ['ennrollmentTwo', o => o.Enrollment >= 100 && o.Enrollment < 1000],
        ['ennrollmentThree', o => o.Enrollment >= 1000 && o.Enrollment < 5000],
        ['ennrollmentFour', o => o.Enrollment >= 5000]
    ],
    result = data.filter(o => fn.some(([k, f]) => filters[k] && f(o)));

console.log(result);


0 commentaires

1
votes

Je suppose que vous voulez faire ceci:

filteredArray = data.filter(function (d) {
    // if any condition at all is fulfilled, keep the item
    return filterByClassification(d) 
        || filterByControl(d) 
        || filterByEnrollment(d);
});`

Voici une version plus verbeuse. J'ai séparé le filtre en une fonction pour chaque propriété:

Et je ne sais pas si cela est pertinent pour vous, mais j'ai également ajouté le cas où il n'y a pas de jeu de filtres pour une propriété .

function filterByClassification(d){
    return (filters.required && d.MenB_Classification === "Required")
        || (filters.recomended && d.MenB_Classification === "Recommended")
        || (filters.notRequired && d.MenB_Classification === "NOT Required")
        // or no filter set for MenB_Classification
        || (!filters.required && !filters.recomended && !filters.notRequired);
}

function filterByControl(d){
    return (filters.publics && d.CONTROL === "Public")
        || (filters.privates && d.CONTROL === "Private")
        // or no filter set for CONTROL
        || (!filters.publics && !filters.privates);
}

function filterByEnrollment(d){
    return (filters.ennrollmentOne && d.Enrollment < 100)
        || (filters.ennrollmentTwo && d.Enrollment >= 100 && d.Enrollment < 1000)
        || (filters.ennrollmentThree && d.Enrollment >= 1000 && d.Enrollment < 5000)
        || (filters.ennrollmentFour && d.Enrollment > 5000)
        // or no filter set for Enrollment
        || (!filters.ennrollmentOne && !filters.ennrollmentTwo && !filters.ennrollmentThree && !filters.ennrollmentFour); 
}


filteredArray = data.filter(function (d) {
    // for every property, there must be one filter fulfilled
    return filterByClassification(d) 
        && filterByControl(d) 
        && filterByEnrollment(d);
});

alors que votre code était équivalent à:

var data = [{ MenB_Classification: "NOT Required", CONTROL: "Public", Enrollment: "892" }, { MenB_Classification: "Required", CONTROL: "Private", Enrollment: "1601" }, { MenB_Classification: "NOT Required", CONTROL: "Private", Enrollment: "447" }, { MenB_Classification: "NOT Required", CONTROL: "Public", Enrollment: "1203" }, { MenB_Classification: "Required", CONTROL: "Private", Enrollment: "32" }, { MenB_Classification: "NOT Required", CONTROL: "Public", Enrollment: "98" }, { MenB_Classification: "Recommended", CONTROL: "Private", Enrollment: "654" }, { MenB_Classification: "NOT Required", CONTROL: "33033764030", Enrollment: "345318" }, { MenB_Classification: "NOT Required", CONTROL: "Private", Enrollment: "13324" }, { MenB_Classification: "Recommended", CONTROL: "Private", Enrollment: "39" }, { MenB_Classification: "NOT Required", CONTROL: "Private", Enrollment: "4" }, { MenB_Classification: "NOT Required", CONTROL: "Private", Enrollment: "910" }, { MenB_Classification: "NOT Required", CONTROL: "Private", Enrollment: "23453" }],
    filters = {
        required: true,
        recomended: true,
        notRequired: false,
        publics: true,
        privates: true,
        ennrollmentOne: true,
        ennrollmentTwo: false,
        ennrollmentThree: false,
        ennrollmentFour: false,
    },
    filteredArray = data.filter(function (d) {
      return ( // check MenB_Classification
           (filters.required && d.MenB_Classification === "Required")
        || (filters.recomended && d.MenB_Classification === "Recommended")
        || (filters.notRequired && d.MenB_Classification === "NOT Required")
      ) && ( // check CONTROL
           (filters.publics && d.CONTROL === "Public")
        || (filters.privates && d.CONTROL === "Private")
      ) && ( // check Enrollment
           (filters.ennrollmentOne && d.Enrollment < 100)
        || (filters.ennrollmentTwo && d.Enrollment >= 100 && d.Enrollment < 1000)
        || (filters.ennrollmentThree && d.Enrollment >= 1000 && d.Enrollment < 5000)
        || (filters.ennrollmentFour && d.Enrollment > 5000)
      );
    });

console.log(filteredArray);


3 commentaires

J'ai du mal à comprendre la différence dans notre code et pourquoi votre code a fonctionné et le mien n'a pas fonctionné. Bref, merci. C'est exactement ce que je voulais.


@NigelDcruz J'étais un peu pressé. Je regroupe les conditions par propriété. Au moins une condition pour chaque propriété doit être true . Votre code vous a simplement demandé si une condition était remplie. Donc, si filters.required était rempli, il ne se souciait plus des filtres pour CONTROL ou Enrollment.


@NigelDcruz J'ai ajouté un exemple plus détaillé