[JS] Ausführliche Erläuterung gängiger Array-Traversal-Methoden in JS (forEach, map, filter, sort, Reduce, every)

       In der Syntax von ES6 wurden Arrays mehrere neue Methoden im Zusammenhang mit der Traversierung hinzugefügt. Obwohl diese Funktionen im Wesentlichen syntaktischer Zucker sind, kann Code theoretisch ohne sie geschrieben werden. Aber ihre Existenz macht unsere Geschäftsabwicklung viel bequemer, daher ist es sehr wichtig, sie in der tatsächlichen Entwicklung zu beherrschen. Für Schüler, die sie zum ersten Mal treffen, sind sie möglicherweise nicht besonders einfach zu verstehen.In diesem Artikel werden konkrete Fälle verwendet, um ihre Grammatik und Verwendung im Detail zu erklären.

        Was alle Array-Methoden gemeinsam haben: Die Parameter erhalten eine Callback-Funktion

        Alle Parameter in den folgenden Callback-Funktionen sind Formalparameter. Das heißt, wenn Sie forEach als Beispiel verwenden, müssen Sie die Parameter nicht als element , index und array schreiben . Sie werden sehen, dass ich viele benutzerdefinierte Parameternamen verwenden werde , um sie darzustellen, Sie müssen die Parameter nur der Reihe nach .

Inhaltsverzeichnis

1. für jeden

2. Karte

3. filtern

4. sortieren

5. reduzieren

6. alle


1. für jeden

        Grundlegende Syntax:

forEach((element, index, array) => { /* … */ }) // return undefined

        Element bezieht sich auf jedes Element im Array, Index bezieht sich auf den Index, der jedem Element entspricht, und Array bezieht sich auf das Array selbst. Aber wenn Sie es über arr.forEach() schreiben, wird das dritte Parameter-Array oft nicht benötigt . forEach gibt keinen Wert zurück

        Erstens denke ich, die am einfachsten zu verstehende und am häufigsten verwendete Array-Methode: forEach. forEach ist im Grunde ein Ersatz für die for-Schleife, die sich am besten zum Schleifen von Arrays eignet und auch zum Schleifen anderer schleifenfähiger Daten (wie Nodelist, Map und Set) verwendet werden kann. Es hat selbst keinen Rückgabewert und führt nur Schleifenoperationen basierend auf der Datenmenge aus.

        Eine übliche Verwendung von forEach ist das Durchlaufen einer nodeList (Knotensammlung) und das Ausführen einheitlicher Operationen für mehrere Objekte im Dom. Schauen Sie sich das Beispiel unten an.

         const inventors = [
            { first: 'Albert', last: 'Einstein', year: 1879, passed: 1955 },
            { first: 'Isaac', last: 'Newton', year: 1643, passed: 1727 },
            { first: 'Galileo', last: 'Galilei', year: 1564, passed: 1642 },
            { first: 'Marie', last: 'Curie', year: 1867, passed: 1934 },
            { first: 'Johannes', last: 'Kepler', year: 1571, passed: 1630 },
            { first: 'Nicolaus', last: 'Copernicus', year: 1473, passed: 1543 },
            { first: 'Max', last: 'Planck', year: 1858, passed: 1947 },
            { first: 'Katherine', last: 'Blodgett', year: 1898, passed: 1979 },
            { first: 'Ada', last: 'Lovelace', year: 1815, passed: 1852 },
            { first: 'Sarah E.', last: 'Goode', year: 1855, passed: 1905 },
            { first: 'Lise', last: 'Meitner', year: 1878, passed: 1968 },
            { first: 'Hanna', last: 'Hammarström', year: 1829, passed: 1909 }
        ];

        // 选择dom元素
        const list = document.querySelector('.list')

        // 对数组进行遍历,数组中每有一个元素就添加一个dom对象
        inventors.forEach(function(inventor, index) {
            const listItem = document.createElement('li')
            listItem.textContent = `${index}: ${inventor.first},
            born ${inventor.year}`
            list.appendChild(listItem)
        })

        // 箭头函数写法:
        inventors.forEach((inventor, index) => {
            const listItem = document.createElement('li')
            listItem.textContent = `${index}: ${inventor.first},
            born ${inventor.year}`
            list.appendChild(listItem)
        })

Hier sind zwei weitere Nutzungsszenarien für forEach:

    <button class="div">click me</button>
    <button class="div">click me</button>
    <button class="div">click me</button>
    <button class="div">click me</button>
    <button class="div">click me</button>        
     
      <script>
        // 获取所有button,赋予他们新的内容,并且绑定事件
        const buttons = document.querySelectorAll('.div')
        buttons.forEach((button, index) => {
            button.textContent = '我是一个按钮'
            button.addEventListener('click', () => {
                console.log('我是一个按钮, 并且我的缩印是' + index)
            })
        })
     </script>
        
        // 根据刚才的inventors数组,计算所有科学家生命总长度    
        let totalYearsLived = 0

        inventors.forEach(function(inventor) {
            let yearLived = inventor.passed - inventor.year
            totalYearsLived += yearLived
        })

        console.log(totalYearsLived) // 861

2. Karte

        Grundlegende Syntax:

let newArr = map((element, index, array) => { /* … */ })
// return new array

        map ähnelt forEach, der größte Unterschied besteht darin, dass ein brandneues Array zurückgegeben wird. Das ursprüngliche Array wird nicht verändert , Element, Index und Array haben die gleiche Bedeutung wie forEach.

        Die folgenden zwei Beispiele veranschaulichen die grundlegende Verwendung von map:

        const inventors = [
            { first: 'Albert', last: 'Einstein', year: 1879, passed: 1955 },
            { first: 'Isaac', last: 'Newton', year: 1643, passed: 1727 },
            { first: 'Galileo', last: 'Galilei', year: 1564, passed: 1642 },
            { first: 'Marie', last: 'Curie', year: 1867, passed: 1934 },
            { first: 'Johannes', last: 'Kepler', year: 1571, passed: 1630 },
            { first: 'Nicolaus', last: 'Copernicus', year: 1473, passed: 1543 },
            { first: 'Max', last: 'Planck', year: 1858, passed: 1947 },
            { first: 'Katherine', last: 'Blodgett', year: 1898, passed: 1979 },
            { first: 'Ada', last: 'Lovelace', year: 1815, passed: 1852 },
            { first: 'Sarah E.', last: 'Goode', year: 1855, passed: 1905 },
            { first: 'Lise', last: 'Meitner', year: 1878, passed: 1968 },
            { first: 'Hanna', last: 'Hammarström', year: 1829, passed: 1909 }
        ];
        
        // 得到所有inventor的全名,并将他们组成一个新的数组
        let fullnameArr = inventors.map(function(inventor) {
            return inventor.first + ' ' + inventor.last
        })

        // 箭头函数写法
        let fullnameArr = inventors.map(inventor => inventor.first + ' ' +   inventor.last)
        const numArr = [1, 4, 98, 170, 35, 87]
        
        // 得到numArr中每一个数字的2倍
        let doubleNumArr = numArr.map(num => num*2)
    
        console.log(doubleNumArr) //  [2, 8, 196, 340, 70, 174]

3. filtern

        Grundlegende Syntax:

filter((element, index, array) => { /* … */ } )
// return shallow copy

        filter ist eine weitere Array-Methode mit einer Syntax, die map und forEach sehr ähnlich ist. filter Chinesisch ist filtern, besonders geeignet zum Extrahieren qualifizierter Arrays in einem Array. Jede Durchlaufrunde gibt einen booleschen Wert zurück , und die Elemente, die wahr sind, werden dem neuen Array hinzugefügt , und schließlich gibt der Filter dieses neue Array zurück        

        Filter ist eine Array-Methode, die meiner Meinung nach am zweithäufigsten verwendet wird und extrem einfach zu verwenden ist. Denn oft müssen wir einige Array-Elemente nach Bedingungen filtern, und das Filtern ist zu diesem Zeitpunkt sehr praktisch. Für Anfänger besteht die größte Schwierigkeit darin zu verstehen, dass der Rückgabewert in der Callback-Funktion ein boolescher Wert ist und dieser boolesche Wert normalerweise in Form eines Ausdrucks erscheint. Letztendlich gibt filter jedoch eine flache Kopie des Arrays zurück . Kurz gesagt, das Ändern des Werts der Elemente der flachen Kopie wirkt sich auch auf die Elemente des vorherigen Arrays aus.

        const inventors = [
            { first: 'Albert', last: 'Einstein', year: 1879, passed: 1955 },
            { first: 'Isaac', last: 'Newton', year: 1643, passed: 1727 },
            { first: 'Galileo', last: 'Galilei', year: 1564, passed: 1642 },
            { first: 'Marie', last: 'Curie', year: 1867, passed: 1934 },
            { first: 'Johannes', last: 'Kepler', year: 1571, passed: 1630 },
            { first: 'Nicolaus', last: 'Copernicus', year: 1473, passed: 1543 },
            { first: 'Max', last: 'Planck', year: 1858, passed: 1947 },
            { first: 'Katherine', last: 'Blodgett', year: 1898, passed: 1979 },
            { first: 'Ada', last: 'Lovelace', year: 1815, passed: 1852 },
            { first: 'Sarah E.', last: 'Goode', year: 1855, passed: 1905 },
            { first: 'Lise', last: 'Meitner', year: 1878, passed: 1968 },
            { first: 'Hanna', last: 'Hammarström', year: 1829, passed: 1909 }
        ];

        // 获取所有出生在1500年和1600年之间的科学家
        const fifteen = inventors.filter(function(inventor) {
            return inventor.year >= 1500 && inventor.year < 1600
        })

        // 箭头函数写法
        const fifteen = inventors.filter(inventor => inventor.year >= 1500 && inventor.year < 1600)

        console.log(fifteen)


        // 例子2:获取所有名字中有字母a的科学家
        const nameHasA = inventors.filter(function(inventor) {
           return inventor.last.includes('a')
        })

        // 箭头函数写法
        const nameHasA = inventors.filter(inventor => inventor.last.includes('a'))
        console.log(nameHasA)

4. sortieren

         Grundlegende Syntax:

sort()
sort((a, b) => { /* … */ } ) 
// 返回sort后被改变的原数组

        Die Syntax von sort unterscheidet sich von der vorherigen Methode, Sie können sie direkt aufrufen, ohne Parameter zu übergeben; Sie können auch eine Callback-Funktion zum Vergleich übergeben . Der Zweck von sort besteht darin, die Elemente in einem Array zu sortieren, wobei sich a und b auf das erste Vergleichselement bzw. das zweite Vergleichselement beziehen. Der Rückgabewert ist das sortierte ursprüngliche Array

        Wenn es keine Vergleichsfunktion gibt , sortiert sort die Elemente nach ihrer Unicode- Position. Das heißt: 'Banana' wird vor 'Cat' gerankt, weil b höher ist als c. 110 wird auch vor 20 eingestuft, da 1 höher als 2 ist. Sehen Sie sich bitte die beiden folgenden Beispiele an

        const numArr = [1, 4, 98, 170, 35, 87]

        // 纯数字排序
        const sortNoParams = numArr.sort()

        console.log(sortNoParams) // [1, 170, 35, 4, 87, 98]


        const nameArr = ['Hanna', 'Meitner', 'Blodgett', 'Nicolaus', 'Einstein']
    
        // 字符串排序
        const newNameArr = nameArr.sort()
        console.log(newNameArr) // ['Blodgett', 'Einstein', 'Hanna', 'Meitner', 'Nicolaus']

        Wenn Sie jedoch eine Vergleichsfunktion in sort übergeben, dann wird sort nach der Größe von a und b sortiert, die Grundregeln lauten wie folgt:

比较函数(a, b) Rückgabewert Sortierreihenfolge
> 0 a nach  b _
< 0 ab vor 
=== 0  die a Reihenfolge  einhalten b

        Kurz gesagt, jede Ausführung der Vergleichsfunktion muss eine Zahl zurückgeben: Ist die Zahl größer als 0, wird das Array in aufsteigender Reihenfolge sortiert, ist sie kleiner als 0, wird das Array in absteigender Reihenfolge sortiert. Wenn gleich 0, bleibt die Reihenfolge unverändert. Traditionell geben wir im Allgemeinen 1 und -1 zurück, um größer als 0 bzw. kleiner als 0 darzustellen . Die Verwendung ist wie folgt:

function compareFn(a, b) {
  if (在某些排序规则中,a 小于 b) {
    return -1;
  }
  if (在这一排序规则下,a 大于 b) {
    return 1;
  }
  // a 一定等于 b
  return 0;
}

通常我们把返回值写为1和-1来代表返回值是否大于0
但如果是纯数字之间进行比较,那么以上函数可以简写:
function compareFn(a, b){
    return a - b
}

        Dieses Mal wiederholen wir unser vorheriges Beispiel zum Sortieren eines Arrays von Zahlen, diesmal jedoch mit der Vergleichsfunktion eines Callbacks. Die Ergebnisse werden nach der tatsächlichen Größe der Zahlen sortiert:

        const numArr = [1, 4, 98, 170, 35, 87]

        const sortedArr = numArr.sort(function(a, b) {
            return a - b
        })

        // 箭头函数写法
        const sortedArr = numArr.sort((a, b) => a - b)

        console.log(sortedArr) // [1, 4, 35, 87, 98, 170]


        const nameArr = ['Hanna', 'Meitner', 'Blodgett', 'Nicolaus', 'Einstein']

        const sortName = nameArr.sort((a, b) => {
            if(a < b) {
                return -1
            } else if(a > b) {
                return 1
            }
            return 0
        })

        console.log(sortName) //  ['Blodgett', 'Einstein', 'Hanna', 'Meitner', 'Nicolaus']

5. reduzieren

         Grundlegende Syntax:

reduce((previousValue, currentValue, currentIndex, array) => { /* … */ }
, initialValue)
// 返回一个类型不一定的结果

        Reduce kann als die am schwierigsten zu verstehende und speziellste Funktion in der Array-Methode bezeichnet werden.

        Reduce akzeptiert auch eine Callback-Funktion und einen Anfangswert als Parameter. Diese Callback-Funktion kann 4 Parameter akzeptieren, nämlich den vorherigen Wert (Gesamtwert) , den aktuellen Wert , den aktuellen Index und das Array . Reduce hat einen optionalen zweiten Parameter , der der Anfangswert ist Wert. Wenn nicht gefüllt, beginnt die Traversierung bei Index 1, dem zweiten Element des Arrays , da der Anfangswert des ersten Elements nicht existiert und der Wert des aktuellen Index ebenfalls 1 ist. Wenn Sie den Anfangswert eingeben, ist der aktuelle Index der ersten Durchlaufrunde 0, das aktuelle Element ist ein Array-Element und das vorherige Element wird ebenfalls zum Anfangswert. Gibt das Ergebnis der Callback-Funktion zurück, die das gesamte Array durchläuft

        Reduce ist keine besonders häufig verwendete Array-Methode, aber in einigen Fällen kann es die Komplexität des Codes erheblich reduzieren.Wir werden mehrere Beispiele verwenden, um einige praktische Anwendungen von Reduce zu zeigen.

        const numArr = [1, 4, 98, 170, 35, 87]
        
        // 得到numArr的元素的和
        let sum = numArr.reduce((previous, current) => {
            return previous + current
        })

        console.log(sum) // 395   

        
        // 如果最初值存在的话
        let withInitial = numArr.reduce((previous, current) => {
            return previous + current
        }, 100)

        console.log(withInitial) // 495

Auf den ersten Blick auf den obigen Code sind Sie vielleicht etwas verwirrt, die folgende Tabelle kann Ihnen beim Verständnis helfen

Anzahl der Rückrufe previousValue currentValue currentIndex Rückgabewert
Die erste Durchlaufrunde 1 4 1 5
Die zweite Durchlaufrunde 5 98 2 103
Die dritte Durchlaufrunde 103 170 3 273
Die vierte Durchlaufrunde 273 35 4 308

Unser Array hat sechs Elemente, also wird es insgesamt sechsmal durchlaufen. Das obige Beispiel ist der Ablauf und die Ergebnisse der ersten vier Runden. Hier ist ein weiteres Beispiel für die Verwendung von Reduce, um Werte in einem Array von Objekten zu aggregieren: 

        let shoppingCart = [
            {
                product: 'phone',
                qty: 1,
                price: 500,
            },
            {
                product: 'Screen Protector',
                qty: 1,
                price: 10,
            },
            {
                product: 'Memory Card',
                qty: 2,
                price: 20,
            },
        ];
        
        // 计算购物车内的价格总和
        let total = shoppingCart.reduce(function (previousValue, currentValue) {
            return previousValue + currentValue.qty * currentValue.price;
        }, 0);

        console.log(total) // 550

        Das Obige sind zwei grundlegende Verwendungen von Reduce, und Sie können es auch auf komplexere Szenarien anwenden. Ein weiteres häufiges Szenario besteht darin, Objekte desselben Typs in einem Array in einer Kategorie zu gruppieren, um ein neues Array zu bilden.

const people = [
  { name: 'Kyle', age: 26 },
  { name: 'John', age: 31 },
  { name: 'Sally', age: 42 },
  { name: 'Jill', age: 42 },
]

// 把年龄相同的人分为一组
const peopleGroupedByAge = people.reduce((groupedPeople, person) => {
  const age = person.age

  // 首先给每个存在的年龄段创建一个空数组
  // 然后用push将每个元素放入相应的数组
  if (groupedPeople[age] == null) groupedPeople[age] = []
  groupedPeople[age].push(person)
  return groupedPeople
    }, {}) // 初始值是一个空对象,这样才能使用增加属性

    console.log(peopleGroupedByAge)
/*
  {
    26: [{ name: 'Kyle', age: 26 }],
    31: [{ name: 'John', age: 31 }],
    42: [
      { name: 'Sally', age: 42 },
      { name: 'Jill', age: 42 }
    ]
  }
*/

6. alle

        Grundlegende Syntax:

every((element, index, array) => { /* … */ } ) // return boolean

        Schließlich werden wir mit einer einfacheren Funktion enden: every(). Die Methode every wird verwendet, um zu prüfen, ob alle Elemente in einem Array die Bedingung erfüllen. Wenn eine der Bedingungen nicht erfüllt ist , gibt die Callback-Funktion false zurück . Wenn alle Durchläufe wahr zurückgeben, dann wird jeder schließlich wahr zurückgeben

 Das Konzept von jedem selbst ist leicht zu verstehen, wir verwenden ein Beispiel, um seine Rolle zu veranschaulichen

        const inventors = [
            { first: 'Albert', last: 'Einstein', year: 1879, passed: 1955 },
            { first: 'Isaac', last: 'Newton', year: 1643, passed: 1727 },
            { first: 'Galileo', last: 'Galilei', year: 1564, passed: 1642 },
            { first: 'Marie', last: 'Curie', year: 1867, passed: 1934 },
            { first: 'Johannes', last: 'Kepler', year: 1571, passed: 1630 },
            { first: 'Nicolaus', last: 'Copernicus', year: 1473, passed: 1543 },
            { first: 'Max', last: 'Planck', year: 1858, passed: 1947 },
            { first: 'Katherine', last: 'Blodgett', year: 1898, passed: 1979 },
            { first: 'Ada', last: 'Lovelace', year: 1815, passed: 1852 },
            { first: 'Sarah E.', last: 'Goode', year: 1855, passed: 1905 },
            { first: 'Lise', last: 'Meitner', year: 1878, passed: 1968 },
            { first: 'Hanna', last: 'Hammarström', year: 1829, passed: 1909 }
        ];
    
        // 检查是不是所有发明家的last name都至少4个字母并且出生于1400年以后
        let checkInventors = inventors.every(inventor => {
            return inventor.last.length >= 4 && inventor.year>1400
        })

        console.log(checkInventors) // true

        Abschließend gibt es nur noch eine Sache zu beachten: Alle heute erwähnten Array-Methoden werden keine leeren Array-Elemente durchlaufen.

console.log([1, , 3].every((x) => x !== undefined)); // true
console.log([2, , 2].every((x) => x === 2)); // true

        Die oben genannten sind die gängigen Array-Traversal-Methoden in ES6, deren Beherrschung für das Unternehmen sehr wichtig ist und unter geeigneten Umständen viel Übung erfordert.

Guess you like

Origin blog.csdn.net/a1611107035/article/details/127601634