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 :

Comparer deux ou trois array et avoir les memes valeurs dans toutes les array


Sujet :

JavaScript

  1. #1
    Débutant  
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 096
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 096
    Points : 944
    Points
    944
    Par défaut Comparer deux ou trois array et avoir les memes valeurs dans toutes les array
    Bonjour à tous,

    J'ai un exercice un peu périlleux car je dois comparer deux, trois ou quatre arrays et faire en sorte qu'elles soient identique. Mais surtout que les changements soient reportés dans une autre array, en respectant l'ordre.

    Je m'explique. Je prends des mesures toutes les heures sur un terrain qui sont affichées sur un graphique à deux axe grâce à chartsjs. Mais des fois, un capteur peut être en panne, ou ne pas avoir le même nombre de valeurs dans un espace de temps.

    Par exemple, je prends la température du sol et de l'air. Mon baromètre était aujourd'hui en panne et je l'ai remplacé. Donc dans la journée j'avais six mesures de l'air (dont 3 le matin et trois le soir, et 24 mesure du sol. Dans ce cas, chartjs, m'affiche un peu n'importe comment.

    Ceci parce que dans l'array de la temperature de l'air j'ai 6 index de 0 à 5.
    Et dans l'array de la temperature du sol, j'ai 24 index de 0 à 23.
    Donc si je parcours les deux arrays, depuis l'index 0 à 2, les heures vont correspondre, mais ensuite, il y a une incohérence dans l'affichage des valeurs en fonction du temps.

    L'idée est de comparer les arrays et de fusionner les valeurs.
    Mais attention, c'est plus compliqué que cela car il peut avoir 3 voir 4 array.
    Mais surtout, si des dates sont ajoutées dans l'array de gauche, il faut aussi que des valeurs de 0 soient ajouté dans une autres tables, au même index.

    Voici plus de précisions
    Si je reprends mon exemple de la température du sol et de l'air, la température du sol est affiché dans mon axe Y de gauche, et la temperature de l'air sera affiché dans mon axe Y de droite.

    Pour bien suivre mon problème, rendez vous sur cette page
    http://www.smart-idea.io/perrieres/
    Sélectionner les dates de 03-09-2018 à 05-09-2018, et sélectionner la station 2 et regarder le graph Température.
    (après avoir sélectionner les dates, faite peut-être un ctrl+r, pour avoir un console log un peu plus allégé )
    J'ai fais un console.log
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    console.log("Temperature Success:",data);
    Je continue mon explication.

    Si vous développez "température success", il y a deux objets.
    Le premier objet correspond à la température de l'air dont les valeurs seront affichées sur mon axe Y de gauche car 'y-axis-0'
    Le deuxième objets correspond à la température du sol dont les valeurs seront affichés sur mon axe Y de droite car 'y-axis-1'

    Vous pouvez déjà constater 'labels' où sont les dates et heures.
    Dans le premier objet, il y a 5 index, dans le deuxième objet, il y a 36 index (donc pas 24, car j'ai redémarrer ma station 8 fois)

    Si vous observer l'index 1 de mon deuxième objet, la date est '2018-09-03 19:26:42' mais cette date ne figure pas dans mon premier objet.

    Il faudrait qu'elle figure aussi à l'index 1 et décaler les autres valeurs. Donc index 1 devient index 2 pour donner la place de '2018-09-03 19:26:42' à l'index 1. Mais il faut surtout que dans le premier l'objet , sous datasets->data que l'index 1 devient aussi index 2 pour que l'index 1 prenne la valeur de 0. (0 car aucune valeur est mesurée à ce moment là)
    C'est très important que la valeur correspondant à une date, ait le même index. Voyez-vous le problème?

    Mais ca se complique car si vous regarder le graphique "humidité du sol", il y a 3 même capteurs d'humidité du sol (plantés à des profondeurs différentes) dont les valeurs s'affichent dans l'axes Y de gauche, et dans l'axe Y de droite, il y a un compteur de goutte. Ce qui fait 4 objets dont trois avec 'y-axis-0' et un avec
    'y-axis-1'. Et plus tard, il y aura 5 objets car dans l'axes Y de droite, il y aura les valeurs d'un compteur de goutte et un pluviomètres.


    J'espère que j'ai été bien explicite explicite?
    Vous avez compris qu'il aie deux ou 6 objets, il faut toujours que mes array 'labels' et 'data' ont les mêmes tailles.

    S'il manque une date à un array/objet , donc aussi une valeur dans 'datasets->data', il faudrait ajouter un index dans 'labels' avec la date correspondante aux autres et ajouter la valeur de 0 dans datasets->data et que l'index de cette valeur correspond à l'index de 'labels'.

    Ouha, voyez-vous? ai-je été claire? m'avez-vous compris? et dernière question, comment je peux donc comparer, fusionner et injecter une valeur dans une autre array en gardant une correspondance au niveau des index?

    Milles mercis pour vos mumières
    P.
    Il ne suffit pas de tout savoir. Vouloir et persévérer, c'est déjà presque tout!

  2. #2
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 739
    Points
    4 739
    Par défaut
    J'ai pas tout lu, t'a lair de te compliquer la vie.

    En JavaScript les tableaux n'existent pas vraiment au sens stricte du terme comme dans les autres langages, ce sont des Objets, et on peut utiliser dessus une syntaxe comme pour les tableaux, si on veut, ou pas.
    mais il y a aussi toute un panoplie de méthodes qui peuvent être utilisées pour trier, parcourir, modifier les valeurs de manière conditionnelles etc..
    et tu a aussi la méthode assign.

    => https://developer.mozilla.org/fr/doc.../Object/assign
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  3. #3
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 637
    Points : 66 656
    Points
    66 656
    Billets dans le blog
    1
    Par défaut
    Personnellement je réfléchirais différemment.
    J'indexerai chaque relevé avec une heure, soit dans un array littéral, soit dans un json
    Car si tu as à la suite dans ton arrays les relevés et que tu n'en a que 3 sur 6 par exemple. Qu'est ce qui te permet de dire que ce sont les 3 premiers, les 3 derniers , ceux du milieux, les 1 - 4 - 6 ou les 2 - 3 - 4 ...

    Cela permet de lier un relevé à un temps donné et ainsi gérer les trous de relevés
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  4. #4
    Invité
    Invité(e)
    Par défaut
    bj,

    déjà bravo pr avoir été clair la plupart des postes à rallonge sont souvent fumeux mais les steps pr reproduire étaient bien décrites
    simplifions qd même les données et la reproduction
    soient a,b,c trois arrays...de taille 4 (mais pourraient être de taille différente...)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    var a = ['a','b','c','d']
    var b = ['a','c','e','h']
    var c = ['b','c','d','f']
    les lettres représentent des dates (comprendre que elles respectent un ordre (ici alphabétique)). Lettres parce que plus court, moins chiant à écrire.

    à chaque el de a est associée une valeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    val_a = [0,1,2,3]
    val_b = [4,0,2,3]
    val_c = [0,1,5,1]
    la demande de pierrot est de récupérer les 3-uplets associés à chaque lettre

    ici
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    'a':<0,4,0> //la premiere valeur correspond au tableau a/val_a
    'b':<1,0,0>
    'c':<2,0,0>
    'd':<3,0,5>
    'e':<0,2,0>
    'f':<0,0,1>
    'h':<0,3,0>
    SI on s'embarque dans cette piste: on récupère trivialement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    labels_a = labels_b = labels_c = ['a',...',h']
    data_a = tuple(0)
    data_b = tuple(1)
    data_c = tuple(2)
    (où tuple(x) représente la colonne x)

    la construction des labels est ballourde
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    var allData = [a,b,c]
    var dates = new Set([].concat(...allData))
    dates = [...dates].sort((x,y)=>x.localeCompare(y))
     
    la construction des tuples aussi
    var tuples = dates.map(l=>{
        //pas efficient, ne PAS faire
        return allData.map(ad=>{
            //si on a trouvé la date pour le jeu de donné "a"  
            return ad.find(lab=>lab==l) 
                || 0 //sinon on retourne 0
        })
    })
    je passe lextraction des valeurs....

    ---------
    concernant le pas efficient, ne PAS faire
    ca depend cb tu as de donnés mais ici on constate tristement que à chaque date, tu vas parcourir TOUS les arrays.
    idem si tu as n tableaux de m elements (m étant la taille la plus grande parmi tous tes tableaux) tu fais nxm ops, cqui d'une part peu être problématique , et d'autre part est triste pour un developpeur

    une possibilité est (tout en conservant cette idée) de directement considérer une map qui est directement construite... et qui représente les tuples
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //tuples associe date=<indexDeLelemTrouve_a, indexDeLelemTrouve_b, ...>
    var tuples = allDates.reduce((acc,ad, i)=>{//i représente le ieme dataset
        ad.forEach((el, indexDeLelem)=>{
            //si le tuple existe déjà je ne le réinitialise pas
            //la subtilité/principe est ici que tester la présence de la date est logarithmique dans une map
            //alors que linéaire dans la premiere approche
            acc[el] = acc[el] || [-1,-1,-1]
            acc[el][i] = indexDeLelem
        })
        return acc;
    },{})//un objet cette fois, pas un array
    ne reste plus qu'à trier les tuples (qui pr linstant sont indexés par ordre de "trouvé"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    var sortedTuples = Object.keys(tuples).sort((a,b)=>a.localeCompare(b)).map(t=>{
        //a noter qu'ici notre tuple peut être de la forme [-1,0,1] qui signifie
        //pas de valeur pour val_a, prendre la valeur à l'index 0 pour val_b, et à l'index 1 pour val_c
        return tuples[t].map((t,i)=>{
            var idx = t[i]
            if( idx == 0 ) return -1
            return allValues[i][idx]
        })
    })
    note: on aurait pu directement construire tuples en une passe (au lieu de stocker l'indexDeLelem on peut directement stocker la valeur... j'ai découplé pour simplicité

    pr répondre stct à ta question sans passer par une variable intermédiaire (ici tuples), als tu peux créer la "encore pire" fonction qui est (pseudo code)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    pour chaque arr de allDates
        pour chaque arr2 de allDates, arr2 different de arr //!!!, O(n^2)
            pour chaque el de arr //!!!now O(mn^2)
                si el dans arr2 ne rien faire
                sinon
                    //now O(mlog(m)n^2)) si dichtomie...
                    ind = recuperer l'indice de l'élément dans arr2 dont la date est la plus proche de el et aussi de ns (temporellement)
                    arr2.splice(ind, 0, el) //on insère lelem à la position ind, on retire aucun élément
                    //on met un 0 dans le tableau des valeurs à la position ind
    je peux detailler le pseudo code si necessaire mais je marrete là car la solution/approche est tres inelegante..

    ps: j'ai pas vérifié mon js mais tu as les grandes lignes
    Dernière modification par NoSmoking ; 11/09/2018 à 10h42.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par SpaceFrog Voir le message
    Personnellement je réfléchirais différemment.
    J'indexerai chaque relevé avec une heure, soit dans un array littéral, soit dans un json ...
    Personnellement, je suis d'accord avec SpaceFrog.

    Si tu galères autant, c'est certainement que ton système est foireux mal conçu.
    Tu essaies de faire rentrer un cube dans un trou rond...


    Revoie la méthodologie, en partant du constat que tu n'auras pas forcément le même nombre de données, ni aux même dates.
    L'idée de SpaceFrog d'indexer sur les dates me semble appropriée, et fiable.


    Quant à la proposition de galerien69...
    Ce n'est pas la peine d'essayer de mettre un cataplasme sur une jambe de bois.

  6. #6
    Invité
    Invité(e)
    Par défaut
    Ce n'est pas la peine d'essayer de mettre un cataplasme sur une jambe de bois.
    je vois pas trop en quoi c'est une jambe de bois.
    tu recuperes des valeurs de diverses sources. #spec
    chaque source te donne une liste de date, et une liste de valeurs. #spec
    ta librairie (ici graphique) t'impose de fournir un tableau label et un tableau values #

    je veux bien savoir comment tu fais.
    parce que t'as liste de valeur []... ou {} pour ta source i, ya un moment tu dois la croiser avec celle des autres sources. Meme combat.

    et si l'idée derrière la tete c'est de dire, utilise ta librairie (graphique) différemment (cqui est pe tout à fait recevable soit dit en passant), l'effort algorithmique est qd même "intéressant" et rapidement prototypable... chez moi c'est 8 lignes... et 5min...
    faut-il s'en écarter en startup

Discussions similaires

  1. rechercher une valeur dans toutes les tables
    Par touness dans le forum Débuter
    Réponses: 1
    Dernier message: 01/12/2011, 11h58
  2. Réponses: 0
    Dernier message: 08/02/2011, 18h46
  3. La meme entete dans toutes les pages
    Par Elwe31 dans le forum ASP.NET
    Réponses: 2
    Dernier message: 18/06/2008, 22h26
  4. Réponses: 9
    Dernier message: 15/05/2007, 14h28
  5. Réponses: 9
    Dernier message: 29/03/2006, 21h41

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