2017-12-07 1 views
1

Ich habe eine verbundene React-Komponente, die ein Array von Plot-Objekten aus dem Status erhält.React-Redux: Filtern eines Arrays von Objekten aus dem Zustand, ob ihre Eigenschaften anderen Arrays aus dem Zustand

Es erhält auch mehrere Arrays von Strings aus Zustand. Wie folgt aus:

function mapStateToProps(state) { 
    return { 
     plots: state.plots.plots, 
     varietyFilter: state.plots.varietyFilter, 
     regionFilter: state.plots.regionFilter, 
     growerFilter: state.plots.growerFilter, 
     plotNameFilter: state.plots.plotNameFilter 
    }; 
} 

sieht Jedes Grundstück etwas wie folgt aus:

{ name, variety, region, grower} 

... mit jeder Eigenschaft eine Zeichenfolge sein.

Ich möchte die Plots filtern, ob die entsprechenden Eigenschaften in diesen Filter-Arrays sind.

Die Standardlösung ist

so etwas wie
const filteredArray = inputArray.filter(a => filterArray.indexOf(a.property) 

verwenden Es gibt drei Probleme, die ich mit diesem Ansatz haben. Erstens, wenn das Filterarray leer ist, werden keine Elemente des gefilterten Arrays passieren, während ich möchte, dass sie alle passieren. Zweitens, was passiert, wenn diese Filter-Arrays, die aus dem Status angezeigt werden, noch nicht initialisiert wurden? Es wird einen Fehler geben, da indexOf nicht verfügbar ist. Drittens möchte ich diese Filtermethoden verketten, aber nur diejenigen ketten, die eine Art Filter-Array initialisiert haben.

Bisher habe ich mit diesem kommen:

if (this.props.plots) { 
      filteredProps = this.props.plots.filter(function(plot) { 
       if (!varietyFilter.indexOf) { 
        return true; 
       } 
       return varietyFilter.indexOf(plot.variety) > -1; 
      }); 
     } 

Das ist nur durch, wenn auch alles zu passieren scheint. Wenn ich die erste Rückgabeanweisung lösche, erhalte ich einen Fehler - die Methode indexOf ist nicht vorhanden, wenn die Komponente zuerst initialisiert wird.

Also, zwei Fragen. Erstens, wie filtere ich ein Array von Objekten dafür, ob eine gegebene Eigenschaft jedes Objekts in einem Array von Strings enthalten ist, die im Zustand existieren können oder nicht? Zweitens, wie mache ich das für eine Reihe von Arrays, die jeweils einer anderen Eigenschaft der Objekte im ursprünglichen Array entsprechen?

+0

Könnten Sie bitte geben typische Werte für jede der Variablen mit dem Sie arbeiten:

const filteredArray = inputArray.filter(a => { if (!filterArray) { filterArray = []; } if (filterArray.length === 0) { return true; } else { return filterArray.includes(a.property); } } 

mutliple Filter Chaining kann getan werden? I.e Plots & Filter? Ich bin mir immer noch nicht sicher, ob es sich um Arrays von Objekten oder um Objekte mit Arrays handelt. – Jaxx

Antwort

1

zu lassen, um alle Elemente passieren, wenn filterArray ein leeres Array ist und Fehler zu vermeiden, wenn es null oder nicht definiert ist, können Sie tun:

const filteredArray = inputArray.filter(a => (filterArray || []).length === 0 || filterArray.includes(a.property)); 

Der Code unten ein leeres Array als Standardwert von filterArray gesetzt in Fall ist es null oder nicht definiert:

filterArray || [] 

und der Teil unterhalb tun, um die Filterung, wenn Arraylänge positiv ist:

|| filterArray.includes(a.property) 

Diese Codes sind Äquivalente:

var filters = [ 
    { prop: 'prop1', filterArray: ['abc', 'def'] }, 
    { prop: 'prop2', filterArray: ['abc'] }, 
    { prop: 'prop3', filterArray: ['abc', 'cde'] } 
]; 

var filteredArray = [...inputArray]; // Copy inputArray 

filters.forEach(filterObj => { 
    filteredArray= filteredArray.filter(a => (filterObj.filterArray || []).length === 0 || filterObj.filterArray.includes(a[filterObj.prop])); 
}); 
+0

Zwei Fragen: 1) Warum überprüfen wir, ob die Länge eines filterArray ODER eines leeren Arrays 0 ist? Wird es für diese Prüfung nicht immer den Wert true zurückgeben, da die Länge eines leeren Arrays immer 0 ist? 2) Wie funktioniert die Überprüfung von filterArray.indexOf (a.property)? Warum müssen wir nicht überprüfen, ob der indexOf-Wert größer als -1 ist? –

+1

2) Ich habe geändert, um array.prototype.includes zu verwenden (es gibt wahr oder falsch zurück). Mit indexOf sollte filterArray.indexOf (a.property)! == -1 1) Falls das Array nicht leer ist, filterArray || [] evaluiert filterArray selbst und die Länge ist positiv so (filterArray || []). length === 0 ergibt false und die endgültige Rückgabe ist filterArray.includes (a.property) – Faly

+0

Das ist schön. Danke, ich habe wirklich ein gutes Gefühl, wenn ich Leute mit solch einem Verständnis von ES6-Funktionen sehe. –

Verwandte Themen