2017-09-18 4 views
2

Guten Morgen,JS-Filterfunktion. Dieses Argument

Ich habe einige Syntax auf der Filterfunktion versucht und ich verstehe nicht, warum ein bestimmter Fall nicht filtert.

Ultimatives Ziel ist es, einen Bereich aus meiner Tabelle zu erhalten und die Funktion zu verwenden, um einen Wert zu übergeben, der auf die Reichweite herausgefiltert wurde.

Beispiele Nach der Code funktioniert

---- (dies korrekt der Wert 6, entfernt sich ergebende Array ist [0,5,8,0,88,0])

{var range = [0,5,8,0,88,6,0] 

function filtro (excl) { 
    return excl != this; 
} 

var range = range.filter(filtro,6)} 

---- im folgenden Code ich habe die gleiche Anordnung mit einem Google Blatt bewegt wird, und der Code auch wieder richtig [0,5,8,0,88,0]

function advancedFilter(){ 

    var ss = SpreadsheetApp.getActiveSpreadsheet(); 

    var sheet = ss.getSheetByName("Testes"); 

    var range = sheet.getRange("A3:A9").getValues(); 


    function filtro (excl) { 
    return excl != 6; 
} 

    var range = range.filter(filtro) 
} 

--- Doch dieses letzte Stück Code, wenn ich die beiden Ideen oben fusionieren ausfällt und kehrt [0,5,8,0,88,6,0], wobei der Bereich unverändert

function advancedFilter(){ 
    var ss = SpreadsheetApp.getActiveSpreadsheet(); 

    var sheet = ss.getSheetByName("Testes"); 

    var range = sheet.getRange("A3:A9").getValues(); 

    function filtro (excl) { 
    return excl != this; 
} 

    var range = range.filter(filtro,6) 
} 

Irgendwelche Hinweise?

+0

Kein Wert von 'advancedFilter()' Aufruf zurückgegeben wird. Was protokolliert "console.log (Bereich)" in der letzten Zeile der Funktion "advancedFilter"? Warum benutzt du 'var range' zweimal? – guest271314

Antwort

2

Das Problem hier ist, dass die result of sheet.getRange("A3:A9").getValues() is an array of arrays of objects. Sie sagen, Sie filtern das Array [0,5,8,0,88,6,0], aber seine Struktur ist eigentlich ein Array von Arrays mit Objekten innerhalb: [[new Number(0)],[new Number(5)],[new Number(8)],[new Number(0)],[new Number(88)],[new Number(6)],[new Number(0)]].

Das erklärt, warum Ihr excl != 6 Test korrekt filtert, weil [new Number(6)] != 6 eigentlich false ist. Für einen nicht strikten Vergleich mit einem Primitiv mit Zahlen wird das linke Array in die String-Repräsentation seines Inhalts umgewandelt, der in diesem Fall "6" ist (was die String-Repräsentation von new Number(6) ist). "6" ist gleich 6 im nicht strikten Vergleich, so ergibt die Ungleichheitsoperation !=false.

Die excl != this Prüfung fehlschlägt, weil filter seine thisArg auf ein Objekt nötigt, so ist es wie new Number(6).Da das Array und das Objekt Number beide Objekte sind, gibt JavaScript keinen Zwang ein und überprüft einfach, ob sich das gleiche Objekt auf beiden Seiten des Operators befindet. In diesem Fall handelt es sich um zwei verschiedene Objekte, sodass die Ungleichheitsoperation !=true ergibt.

  • Sie können this zurückdrehen in eine Reihe primitiver durch einen unären + Operator: excl != +this.
  • Darüber hinaus können Sie einen noch klareren Vergleich durchführen, indem Sie das erste Element aus dem Array, das von filer betrachtet wird, herausziehen (da Ihre Eingabe nur eine Spalte ist) und es in ein Primitiv umwandeln: +excl[0] != +this.
  • Schließlich, da beide Seiten jetzt ein primitive sind, können Sie einen strengen Vergleich verwenden: +excl[0] !== +this
+0

Danke. Sehr gute und klare Erklärung. Habe viel gelernt nach den Details darüber. Mein Problem wurde gelöst. –

0

Wenn jedes Element in der Auflistung zurückgegeben von sheet.getRange("A3:A9").getValues(); ein Objekt ist, dann werden die Tests immer scheitern, weil Ihr this Wert wird auch ein Objekt sein, und so wird es ein Identitätsvergleich sein, die scheitern.

Um dies zu beheben, advancedFilter() Lauf in Strict-Modus, machen, so dass Sie Ihre Nummer 6 ein primitiver als this Wert bleibt. Auf diese Weise wird die == ihren abstrakten Vergleich mit Zwang machen.

function advancedFilter() { 
    "use strict"; // <===== strict mode 

    var ss = SpreadsheetApp.getActiveSpreadsheet(); 

    var sheet = ss.getSheetByName("Testes"); 

    var range = sheet.getRange("A3:A9").getValues(); 

    function filtro (excl) { 
    return excl != this; // `this` is a primitive instead of a `Number` object 
    } 

    var range = range.filter(filtro, 6); 

    console.log(range); 

    return range; 
} 
0

Ohne Verwendung von this ist es besser, eine Funktion zurückzugeben.

function advancedFilter() { 

var ss = SpreadsheetApp.getActiveSpreadsheet(); 

var sheet = ss.getSheetByName("Testes"); 

var range = sheet.getRange("A3:A9").getValues(); 

function filtro (excl) { 
    return function (elem) { 
     return elem != excl; 
    } 
} 

var range = range.filter(filtro(6)); 

} 
+0

Das ist eine Alternative, aber erklärt nicht wirklich, was mit dem Code falsch ist. – spanky

Verwandte Themen