プロジェクトの実践の中でもっと優雅な方法で配列の問題を処理します


最近のプロジェクトでは、配列内のある要素のフィールドを抽出して分類したり、配列内のある要素が判断条件を満たしているかどうかを判断したりするなど、配列を多く処理するシーンに遭遇しました.
ネット上では、forループの代わりにES 5の新しいAPIを使用する文章が多く、APIの使い方を詳しく議論したり、それぞれの性能を詳しく分析したり、使用中の注意点を整理したりしています.そこで,本稿ではこれらのAPIの詳細な使用方法について述べるのではなく,個人的な観点から,プロジェクトの実践で遭遇した配列遍歴をより優雅に処理できる例をまとめた.
1、Setを使用して配列の重量除去と要素除去の問題を処理するSetはes 6に追加されたデータ構造であり、配列と非常に似ているが、メンバーの値は一意であり、重複した値はない.4つの意味化されたAPIを提供します.
  • add(value):値を追加し、Set構造自体を返します.
  • delete(value):値を削除し、削除に成功したかどうかを示すブール値を返します.
  • has(value):値がSetのメンバーであるかどうかを示すブール値を返します.
  • clear():すべてのメンバーを消去し、値を返さない.

  • 参考自@阮一峰先生の『ECMAScript 6入門』
    では、Setで何をすることができますか?
    最初の使い方は、配列が重くなります.1次元配列については,まずそれをSetに変換し,...解構演算子と組み合わせて配列に再変換し,重量除去の目的を達成することができる.例を見てください.
    const arr = [1, 1, 2, 2, 3, 4, 5, 5]
    
    const newArr = [...new Set(arr)]
    
    console.log(newArr)
    
    // [1, 2, 3, 4, 5]

    この方法は、要素が「オブジェクト」である配列には効果的ではありません.
    const arr = [{ name: 'Alice', age: 12 }, { name: 'Alice', age: 12 }, { name: 'Bob', age: 13 }]
    
    const newArr = [...new Set(arr)]
    
    console.log(newArr)
    
    // [{ name: 'Alice', age: 12 }, { name: 'Alice', age: 12 }, { name: 'Bob', age: 13 }]

    これは、Setが要素が重複しているかどうかを判断する方法が===演算子に似ており、2つのオブジェクトは常に等しくないからである.
    重量除去に加えて、Setによって提供されるdelete()の方法も非常に実用的である.従来の方法では、配列で指定された要素を削除するには、まずその要素が下付き文字を取得し、splice()の方法で下付き文字に対応する要素を削除する必要があり、理解上混乱を引き起こしやすい.
    //           2   
    const arr = [1, 2, 3]
    const index = arr.indexOf(2)
    if (index !== -1) {
        arr.splice(index, 1)
    }
    
    console.log(arr)
    
    // [1, 3]
    Setを使用すると、より明確になります.
    const arr = [1, 2, 3]
    const set = new Set(arr)
    set.delete(2)
    arr = [...set]
    
    console.log(arr)
    
    // [1, 3]

    2.map()メソッドとオブジェクトを使用して文法抽出フィールドを解体する
    バックグラウンドインタフェースに返されるデータを要求すると、次のようなデータフォーマットが発生する可能性があります.
    studentInfo = [
      { name: 'Alice', age: 18, no: 2 },
      { name: 'Bob', age: 16, no: 5 },
      { name: 'Candy', age: 17, no: 3 },
      { name: 'Den', age: 18, no: 4 },
      { name: 'Eve', age: 16, no: 1 },
    ]

    名前リスト、年齢リスト、番号リストを取得する場合は、map()を使用してオブジェクトの解構構文に合わせて簡単に処理できます.
    const nameList = studentInfo.map(({ name }) => name)
    const ageList = studentInfo.map(({ age }) => age)
    const noList = studentInfo.map(({ no }) => no)
    
    // nameList: [ 'Alice', 'Bob', 'Candy', 'Den', 'Eve' ]
    // ageList: [ 18, 16, 17, 18, 16 ]
    // noList: [ 2, 5, 3, 4, 1 ]

    3.filter()メソッドとオブジェクトを用いて構文フィルタ配列を解く
    上の例に続き、「年齢が17歳未満」の新しいリストを取得したい場合は、どうすればいいですか?map()の方法と同様に、filter()の方法で濾過することができます.
    const newStudentInfo = studentInfo.filter(({ age }) => {
      return age <= 17
    })
    
    /*
    newStudentInfo: [
      { name: 'Bob', age: 16, no: 5 },
      { name: 'Candy', age: 17, no: 3 },
      { name: 'Eve', age: 16, no: 1 }
    ]
    */

    4、includes()の方法で2つの配列の差を求める
    次の2つの配列があるとします.
    var a = [1, 2, {s:3}, {s:4}, {s:5}]
    var b = [{s:2}, {s:3}, {s:4}, 'a']

    どうやって差集を見つけますか?従来の方法ではObject形式でhash化する必要があるかもしれませんが、.includes()の方法でより優雅で便利に差分セットを見つけることができます.コードは以下の通りです.
    var a = [1, 2, {s:3}, {s:4}, {s:5}].map(item => JSON.stringify(item))
    var b = [{s:2}, {s:3}, {s:4}, 'a'].map(item => JSON.stringify(item))
    
    var diff = a.concat(b)
                .filter(v => !a.includes(v) || !b.includes(v))
                .map(item => JSON.parse(item))
                
    // diff: [1, 2, {s:5}, {s:2}, "a"]

    なぜJSON.stringify()なのかというと、2つの「オブジェクト要素」が等しいかどうかを比較するため、直接「オブジェクト」として比較することはできません(永遠に等しくありません).
    5、後記
    本文の幅は比較的に短くて、難易度も比較的に簡単で、以上はすべていくつかのふだんの実践の中で発見した技巧で、読者たちに啓発することができることを望みます.もしあなたも優雅で面白いテクニックがあれば、私と交流して分かち合ってみてください.