IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Filtre sur un tableau


Sujet :

JavaScript

  1. #1
    Membre confirmé
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2018
    Messages
    184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Novembre 2018
    Messages : 184
    Par défaut Filtre sur un tableau
    Bonjour,

    J'ai ce JSON :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    [{
                "id": 1,
                "parcelles": [
                    "BE0152",
                    "AO0559",
                    "AO0560"
                ]
            },
            {
                "id": 2,
                "parcelles": [
                    "AP0055"
                ]
            },
            {
                "id": 3,
                "parcelles": [
                    "BE0208",
                    "BE0290",
                    "BE0309"
                ]
            },
            {
                "id": 4,
                "parcelles": [
                    "BE0152",
                    "BE0151"
                ]
            }
    ]
    La question que je veux poser à ce JSON est de me redescendre tous les enregistrements dont l'array parcelles contient une certaine valeur.
    Par exemple, tous les enregistrements dont l'array parcelles contient la valeur "BE0152".

    Comment faire ? J'ai déjà ce code que j'ai trouvé sur un forum. La fonction filter demande un filtre (qui est un json) en paramètre, l'idée est d'adapter ce code pour prendre en compte la fameuse demande ci-dessus.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
          async filter(filtre){
     
        this.filterByInsee(this.insee).then((res) => {
          var records = res.records;
     
    			records = records.filter((item) => {
            for (var key in filtre) {
              if (item[key] === undefined || item[key] != filtre[key]){
                return false;
              }
              return true;
            }
          })
     
          console.log(records);
        })
       }
    Merci pour vos retours

    Sylvain

  2. #2
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Salut,

    Je te propose ce petit code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    var json =
        [
            {
                "id": 1,
                "parcelles": [
                    "BE0152",
                    "AO0559",
                    "AO0560"
                ]
            },
            {
                "id": 2,
                "parcelles": [
                    "AP0055"
                ]
            },
            {
                "id": 3,
                "parcelles": [
                    "BE0208",
                    "BE0290",
                    "BE0309"
                ]
            },
            {
                "id": 4,
                "parcelles": [
                    "BE0152",
                    "BE0151"
                ]
            }
        ]
     
     
     
     
    function filter(json, valeur) {
        var list = []
        for (var obj of json) {
            if (obj.parcelles.includes(valeur)){
                list.push(obj)
                console.log(obj);        }
        }
        return list
    }
     
    // Exemples :
     
    var res = filter(json, "BE0152")
    console.log("résultat(s) -->", res);
     
     res = filter(json, "BE0151")
    console.log("résultat(s) -->", res);
     
    res = filter(json, "BE0208")
    console.log("résultat(s) -->", res);
    Une autre solution avec la méthode filter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    function filter2(json, valeur) {
        return json.filter((obj => {
            if (obj.parcelles.includes(valeur)) {
                console.log(obj);
                return true
            }
        }))
    }
     
    // Exemples :
     
    var res = filter2(json, "BE0152")
    console.log("résultat(s) -->", res);
     
    res = filter2(json, "BE0151")
    console.log("résultat(s) -->", res);
     
    res = filter2(json, "BE0208")
    console.log("résultat(s) -->", res);

  3. #3
    Membre confirmé
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2018
    Messages
    184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Novembre 2018
    Messages : 184
    Par défaut
    Merci pour ton retour :-)

    Comment ferais tu si tu devais croiser une demande pour redescendre tous les enregistrements dont l'array parcelles contient "BE0152" et "BE0153" ainsi que l'id = 3 ?
    Cette requête ne redescendrait rien mais juste pour le principe.

    Mon filtre doit se présenter comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    var filter = {
    "id" : 3,
    "parcelles" : ["BE0153", "BE0152"]
    }
    Sylvain

  4. #4
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Salut,
    Citation Envoyé par sylvain257 Voir le message
    Comment ferais tu si tu devais croiser une demande pour redescendre tous les enregistrements dont l'array parcelles contient "BE0152" et "BE0153" ainsi que l'id = 3 ?
    Cela dépend, si l'id est unique je chercherais d'abord cela et alors si je trouve l'objet en question eh bien je vérifierais si parcelles contient "BE0152" et "BE0153"...

    D'ailleurs on peut même donner une liste contenant toutes les valeurs à chercher, exemple : var valeurs = ["BE0152", "BE0153"]...

    Avant de le faire il faudrait donc nous dire si l'id est unique ou non...

  5. #5
    Membre confirmé
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2018
    Messages
    184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Novembre 2018
    Messages : 184
    Par défaut
    Oui l'id est unique.

    C'est pour une application de visualisation des données du cadastre.

    J'ai une liste de propriétaires, qui possèdent une ou plusieurs parcelles.

    Quand je clique sur une parcelle, je souhaite avoir tous les propriétaires de cette parcelle. Je peux le faire côté serveur avec mon API mais j'aimerais le faire côté client, pour éviter de tirer sur le serveur d'une part, et surtout de réutiliser ce filtre pour une recherche multicritères.


    MAJ :
    Ce code semble fonctionner. Qu'en pensez-vous ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    var recs = res.records;
     
          recs = recs.filter(item => {
            for(var key in filtre){
              if(key === "parcelles"){
                if(filtre[key].find((elmt) => item[key].includes(elmt))){
                  return true;
                } else {
                	return false;
                }
              }
              if(item[key] === "undefined" || item[key] != filtre[key]){
              	return false
              }
            }
            return true;
          })
          console.log(recs);

  6. #6
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Citation Envoyé par sylvain257 Voir le message
    MAJ :
    Ce code semble fonctionner. Qu'en pensez-vous ?
    Ben l'as-tu testé ? Ça donne quoi de ton coté ?

    De notre coté, il est plus difficile de faire le teste car tu ne nous donnes pas un exemple fonctionnel... Il nous faut deviner ce que tu as voulu faire et ensuite ajouter ce qui manque pour pouvoir tester, ce n'est pas forcément évident, tu ne nous facilites pas la tâche...

    Dans ton code :

    - recs semble être le tableau json que tu as donné dans ton premier fil.

    mais le problème c'est que cela ne colle pas avec la suite...

    On ne sait pas ce qu'est la variable filtre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    recs = recs.filter(item => {
            for(var key in filtre){
              if(key === "parcelles"){
    On peut deviner que cela devrait être un élément du tableau recs (qui contient des objets ayant une clé parcelles...
    mais dans ce cas il fallait plutôt écrire for(var key in item)...

    En plus utiliser la méthode filter fait parcourir tout le tableau alors qu'on devrait s’arrêter dés qu'on trouve l'objet ayant l'ID voulu...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    recs = recs.filter(item => {
            for(var key in filtre){
              if(key === "parcelles"){
                if(filtre[key].find((elmt) => item[key].includes(elmt))){
                  return true;
                }
    Je ne comprends pas la condition if à la ligne 4... filtre[key] et item[key] renvoient tous les deux au tableau parcelles ?

    Peut-être que pour toi (dans ton esprit) il y a deux tableaux parselles ? Un qui est une propriété des objets ( item[key]) et l'autre qui est la liste des "parselles" (filtre[key]) dont on veut tester la présence dans la passerelle item[key]?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(item[key] === "undefined" || item[key] != filtre[key]){
    Là aussi j'ai du mal à comprendre :

    item[key] ne devrait jamais être indéfini du moins si tu avais écrit for(var key in item) au lieu de for(var key in filtre)...


    **********************

    Si cela t’intéresse j'avais écrit ceci entre temps :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
     
     
    var json =
        [
            {
                "id": 1,
                "parcelles": [
                    "BE0152",
                    "AO0559",
                    "AO0560"
                ]
            },
            {
                "id": 2,
                "parcelles": [
                    "AP0055"
                ]
            },
            {
                "id": 3,
                "parcelles": [
                    "BE0208",
                    "BE0290",
                    "BE0309"
                ]
            },
            {
                "id": 4,
                "parcelles": [
                    "BE0152",
                    "BE0151"
                ]
            }
        ]
     
     
    function is_all_items_in_parcelles(parcelles, items) {
        for (let item of items) {
            if (!parcelles.includes(item)) {
                console.warn(`item: ${item} non trouvé dans [${parcelles}]`);
                return false
            }
            console.log(`item: ${item} trouvé dans [${parcelles}]`);
        }
        return true
    }
     
    function filter1(json, id, valeurs) {
        for (var obj of json) {
            if (obj.id == id) {
                // console.log(`un objet d'ID ${id} a été trouvé :`, obj);
                if (is_all_items_in_parcelles(obj.parcelles, valeurs))
                    return obj
                else return false
            }
        }
    }
     
    // Exemples :
     
    console.log("************* exemple 1 *************");
    var valeurs = ["BE0152", "BE0153"]
    var id = 3
     
    var res = filter1(json, id, valeurs)
    if (res) console.log("l'objet trouvé est", res);
    else console.log("Aucun objet trouvé");
     
    // ------------------
    console.log("************* exemple 2 *************");
     
    valeurs = ["BE0208", "BE0290", "BE0309"]
    id = 3
     
    res = filter1(json, id, valeurs)
    if (res) console.log("l'objet trouvé est", res);
    else console.log("Aucun objet trouvé");
     
    // ------------------
    console.log("************* exemple 3 *************");
    valeurs = ["BE0151", "BE0152", "BE0309"]
    id = 4
     
    res = filter1(json, id, valeurs)
    if (res) console.log("l'objet trouvé est", res);
    else console.log("Aucun objet trouvé");
    Ce code est testable directement, il y a des affichages avec la console qui permettent de bien suivre le déroulement de l’exécution...
    On pourrait faire un code plus concis sans ces console et avec la méthode find à la place de la fonction is_all_items_in_parcelles...

  7. #7
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Je crois avoir mieux compris ce que tu voulais faire, je pense que tu voulais que le filtre soit donné sous la forme d'un objet ayant une propriété "parcelles", du coup il faudrait que filtre soit par exemple comme en ça :
    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    var filtre = {    
        "parcelles": ["BE0152", "BE0153"]
    }

    Ok mais dans ce cas on pourrait se passer de la boucle for mais surtout la condition if(filtre[key].find((elmt) => item[key].includes(elmt))) me semble ne pas convenir car elle est vraie si au moins un élément de filtre[key] se trouve dans item[key] et non si tous les éléments s'y trouvent (or c'est ça que l'on veut).

    Si tu tiens à utiliser la méthode find, on pourrait modifier comme ceci if(!filtre[key].find((elmt) => !item[key].includes(elmt)))... Mais en fait ce serait plus simple d'utiliser dans ce cas la méthode every (cf.exemple ci-dessous)...

    **********
    Dans ton critère de recherche il y a avait aussi l'ID unique, du coup pour suivre ta logique l'objet filtre pourrait être par exemple comme en ça :

    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    var filtre = {
        "id": 3,
        "parcelles": ["BE0152", "BE0153"]
    }

    J'évite aussi d'utiliser la méthode filter car il est plus performent de s’arrêter immédiatement si l'on trouve l'objet avec l'id voulu plutôt que de parcourir tout le tableau dans tous les cas...

    Voici un code avec affichage pour suivre le déroulement de l’exécution testable directement :

    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    var json =
        [
            {
                "id": 1,
                "parcelles": [
                    "BE0152",
                    "AO0559",
                    "AO0560"
                ]
            },
            {
                "id": 2,
                "parcelles": [
                    "AP0055"
                ]
            },
            {
                "id": 3,
                "parcelles": [
                    "BE0208",
                    "BE0290",
                    "BE0309"
                ]
            },
            {
                "id": 4,
                "parcelles": [
                    "BE0152",
                    "BE0151"
                ]
            }
        ]
     
     
     
    function search(filtre, recs) {
        for (let item of recs) {
            if (filtre.id == item.id) {
                // if (!filtre.parcelles.find((elmt) => !item.parcelles.includes(elmt)))
                if (filtre.parcelles.every((elmt) => item.parcelles.includes(elmt))) {
                    console.log(`l'objet ayant l'ID ${filtre.id} répond aux critères du filtre...`);
                    return item;
                }
                else {
                    console.log(`un objet ayant l'ID ${filtre.id} a été trouvé mais il ne répond aux critères du filtre...`);
                    return false
                }
            }
        }
        console.log(`Aucun objet ayant l'ID ${filtre.id} n'a été trouvé...`);
        return false
    }
     
     
    // Exemples
     
    console.log("************* exemple 1 *************");
    var filtre = {
        "id": 3,
        "parcelles": ["BE0152", "BE0153"]
    }
    var res = search(filtre, json)
    console.log(res);
     
     
    console.log("************* exemple 2 *************");
    filtre = {
        "id": 3,
        "parcelles": ["BE0208", "BE0290", "BE0309"]
    }
     
    res = search(filtre, json)
    console.log(res);
     
    console.log("************* exemple 3 *************");
    filtre = {
        "id": 7,
        "parcelles": ["BE0151", "BE0152", "BE0309"]
    }
     
    res = search(filtre, json)
    console.log(res);

  8. #8
    Membre confirmé
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2018
    Messages
    184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Novembre 2018
    Messages : 184
    Par défaut
    En fait, filtre est le paramètre de la fonction comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
        async filter(filtre){
     
            return this.filterByInsee(this.insee).then((res) => {   //// je récupère les parcelles d'une ou plusieurs communes
                var recs = res.records; /// la réponse
     
                recs = recs.filter(item => {
                    for(var key in filtre){
                        if(key === "parcelles"){
                            if(filtre[key].find((elmt) => item[key].includes(elmt))){
                            return true;
                            } else {
                                return false;
                            }
                        }
                        if(item[key] === "undefined" || item[key] != filtre[key]){
                            return false
                        }
                    }
                    return true;
                })
     
                return recs;
     
            })
        }
    De mon côté, le code semble plutôt bien fonctionner, je ne sais pas du tout si cela correspond à des bonnes pratiques, mais ça fonctionne. Et merci pour le code @Beginner.

    Merci pour vos collaborations,

    Sylvain

  9. #9
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Citation Envoyé par sylvain257 Voir le message
    En fait, filtre est le paramètre de la fonction comme suit :
    Oui mais cela ne nous dit pas ce qu'est ce paramètre, j'ai essayé de deviner dans mon message précèdent, peux-tu me dire si c'est bien ça ?

    Comment tu appelles la fonction async filter(filtre) (tu mets quoi à la place de filtre) ?

    Et le nom de cette fonction est le même que la méthode filter ?

    Citation Envoyé par sylvain257 Voir le message
    De mon côté, le code semble plutôt bien fonctionner, je ne sais pas du tout si cela correspond à des bonnes pratiques, mais ça fonctionne.
    Ben lis mon message précédent... (tenir compte de l'id, éviter la méthode filter...) et encore avant je t'avais parlé de la condition if(item[key] === "undefined" || item[key] != filtre[key]) qui est étrange, et d'ailleurs attention "undefined" c'est une chaine de caractères, tu testes donc si item[key] est égale à cette chaine et non si item[key] est indéfini (undefined)...



    PS : Es-tu sûr qu'il fonctionne ton code ?

    Peux-tu tester les exemples que j'ai donnés pour voir... Notamment dans le cas dont tu parlais (où le tableau parcelles contient plus de deux éléments à chercher) :
    Citation Envoyé par sylvain257 Voir le message
    Comment ferais tu si tu devais croiser une demande pour redescendre tous les enregistrements dont l'array parcelles contient "BE0152" et "BE0153" ainsi que l'id = 3 ?



    PS2 : Si quelqu'un a compris le code, une explication serait la bienvenue... Quelque chose doit m'échapper...

  10. #10
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 198
    Par défaut
    Bonjour,
    bien des choses m'échappent également et notamment le fait de déclarer une clé ("parcelles") pour le filtre qui ne devrait donc pas être « reprise en dur » dans la fonction !

    Si l'id est unique il me semble qu'il y aurait matière à faire plus simple.

    ...

  11. #11
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Merci NoSmoking,

    Je trouvais aussi que c'était dommage de ne pas exploiter le fait que l'ID soit unique...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Filtre sur un tableau issu de la base de donnée
    Par Stomac dans le forum Power BI
    Réponses: 3
    Dernier message: 05/04/2019, 14h03
  2. [Plugin] JTABLE - filtre sur un tableau de données
    Par triaguae dans le forum jQuery
    Réponses: 1
    Dernier message: 21/09/2016, 08h26
  3. [VxiR2] Filtre sur un tableau sans faire sauter les lignes sans données
    Par tatayoyo dans le forum Deski
    Réponses: 3
    Dernier message: 20/03/2009, 10h35
  4. [VBA] VBA et filtre sur un tableau
    Par Sergio63 dans le forum SDK
    Réponses: 1
    Dernier message: 30/03/2007, 10h27
  5. Réponses: 5
    Dernier message: 06/01/2007, 11h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo