Pensando attraverso l'applicazione e la rimozione di più filtri in qualsiasi ordine

1

Sto sviluppando un grafico nodo / bordi utilizzando la libreria JavaScript d3 (la lingua non è così importante, questa è una domanda concettuale / di approccio). Il mio grafico ha la capacità di filtrare dinamicamente i nodi sulla base di vari criteri, incluso il tipo e gli attributi specifici. Ad esempio, supponiamo di avere i seguenti oggetti nel mio set di dati:

nodes = [
  {"type": "fruit", "name": "banana", "length": 5},
  {"type": "fruit", "name": "banana", "length": 6},
  {"type": "fruit", "name": "banana", "length": 4},
  {"type": "fruit", "name": "apple", "length": 3},
  {"type": "fruit", "name": "apple", "length": 2},
  {"type": "fruit", "name": "cherry", "length": 1},
  {"type": "animal", "species": "monkey", "name": "kong", "eats": "banana"},
  {"type": "animal", "species": "monkey", "name": "george", "eats": "banana"},
  {"type": "animal", "species": "rabbit", "name": "harvey", "eats": "apple"},
  {"type": "animal", "species": "bird", "name": "bluebird", "eats": "cherry"},
  {"type": "location", "name": "zoo", "residents": ["monkey", "rabbit", "bird"]},
  {"type": "location", "name": "tree", "residents": ["apple", "banana", "cherry"]}
]

I collegamenti (spigoli) vengono generati dinamicamente per gli elementi in base alle loro relazioni. Sono disponibili i seguenti filtri:

  • Tipo - [fruit, animal, location]
  • Nome : filtri basati sul fatto che name stringa contenga testo specifico
  • Lunghezza - non tutti i tipi hanno questa proprietà, ma quelli che lo fanno possono essere filtrati per lunghezza
  • Specie - non tutti i tipi hanno questa proprietà, ma quelli che lo fanno possono essere filtrati per specie

Si supponga anche che una proprietà sia stata aggiunta dinamicamente ad ogni nodo che indica se è attualmente filtrata o meno (cioè un valore booleano). Di default il valore è false (tutti i nodi sono visibili).

Supponiamo che un utente applichi i seguenti filtri:

  1. L'utente applica un filtro ai dati per mostrare solo i nodi in cui type == "fruit" (tutti i valori dei filtri di tutti i nodi sono ora impostati su true eccetto quelli di tipo "frutto")

  2. L'utente applica quindi un filtro ai dati per mostrare solo i nodi in cui name non contiene il carattere 'a' (solo "cherry" non è attualmente filtrato, tutti gli altri nodi 'i valori dei filtri ora sono impostati su true )

  3. L'utente rimuove il filtro applicato in # 1 (ora solo i nodi il cui valore name non contengono il carattere 'a' deve essere visualizzato)

Come faccio a gestire più filtri per assicurarmi che non "annullino" l'un l'altro, ma non abbiano problemi logici se vengono applicati (e non applicati) in ordini diversi?

Nella mia situazione attuale, il passaggio 3 comporterà la visualizzazione di tutti i nodi, ma non è corretto.

Esiste un modo logico per controllare prima di applicare i filtri (ad es. if (node.filtered) {// only apply new filters to unfiltered data} , o il filtro da # 2 deve essere "riapplicato" al set di dati dopo aver rimosso il filtro da # 1 (sto pensando che quest'ultimo) Devo memorizzare tutti i filtri applicati in una lista ordinata (o altra struttura di dati) e quindi riapplicarli in ordine ogni volta che viene rimosso un filtro (non applicato)? O sono troppo complicato?

    
posta Dan 21.09.2016 - 03:11
fonte

1 risposta

3

Se capisco il tuo sistema, i filtri sono congiuntivi, vale a dire che loro E insieme. L'operazione AND è commutativa, quindi l'ordine di applicazione dei filtri non ha importanza. Dovresti sempre essere in grado di catturare i filtri che a livello del suolo sono indipendenti. (Tuttavia, puoi scegliere di esprimere o catturare filtri che non possono essere indipendenti e che dipendono da altri filtri, in questo caso le cose sono più complicate e dovrai adattarle.)

Se si memorizza nella cache ciò che viene filtrato in base all'attuale combinazione di filtri, quando si aggiunge un nuovo filtro non è necessario controllare i nodi che sono già stati filtrati, poiché non importa l'ordine dei filtri e persino se si ri-filtra, quei nodi già rimossi verranno nuovamente rimossi. Pertanto, data la memorizzazione nella cache dei filtri correnti, puoi eseguire un'ottimizzazione sul filtro e applicare solo il nuovo filtro agli altri elementi non filtrati.

Tuttavia, data solo la congiunzione corrente dei filtri e lo stato di filtraggio (memorizzato nella cache) per ciascun nodo: la congiunzione totale corrente, quando rimuovi un filtro, dovrai invertire quella logica e applicare il filtro di rimozione a tutti i correntemente nodi filtrati, anche se puoi lasciare solo i nodi non filtrati. Tuttavia, poiché non si conosce il motivo per cui un elemento si trova nel set filtrato (rimosso), sarà necessario applicare tutti i filtri a ciascun nodo filtrato per ridefinirlo. (Un vantaggio è ovviamente per l'utente che i filtri possono essere rimossi in qualsiasi ordine.)

Se si aveva un conteggio del numero di volte in cui un elemento è stato filtrato, si potrebbe pensare che un filtro in meno per quell'elemento debba diminuire il conteggio del filtro, e quindi a un numero di filtri pari a zero il nodo non deve essere filtrato. Tuttavia, dovresti anche mantenere quel numero di filtri più ampio di quanto descritto sopra (applica il conteggio a tutti gli articoli, non solo quelli attualmente non filtrati).

Si noti che sto descrivendo lo stato del filtro come una cache, poiché si tratta di uno stato copiato derivato da altri stati esistenti, in pratica la definizione di memorizzazione nella cache.

Quando facciamo il caching, l'idea è che speriamo ci aiuti, ma ci vuole del lavoro per mantenere la cache e, ciò che memorizziamo nella cache non è sempre utile per tutti gli scenari. Tuttavia, per definizione di stato derivato, puoi sempre gettare via una cache e rigenerarla da zero.

Il caching è generalmente considerato un'ottimizzazione, che non dovremmo prendere troppo alla leggera. Innanzitutto, ci vuole lavoro per mantenere la cache, e quando il nostro codice è in fase di sviluppo, questo a volte è un onere di manutenzione non necessario. In secondo luogo, non sappiamo per certo che l'ottimizzazione della memorizzazione nella cache, anche se corretta al 100%, rende le cose più lente o più veloci. Questo è il motivo per cui le best practice affermano che non applichiamo ottimizzazioni che aumentano la complessità del codice senza la giustificazione della misurazione.

    
risposta data 21.09.2016 - 04:00
fonte

Leggi altre domande sui tag