[CS]高次関数Day-19


高次関数で学ぶべきこと
  • 一級対象(一級公民)の3つの特徴
  • 高次関数(高次関数)
  • JSで
  • 高次関数
  • を記述する

    一級オブジェクト(first-class citizen)とは?


    JavaScriptでは、一級オブジェクトが特別扱いされます.代表的な一級オブジェクトは関数です.
  • 変数は
  • を割り当てることができる.
  • は、他の関数のパラメータとして
  • を伝達することができる.
  • は、他の関数の結果
  • を返すことができる.
    関数を変数に割り当てることができるため、関数を配列内の要素またはオブジェクトの属性値として保存できます.
    ex)変数に関数を割り当てる(関数式)
    const square = function(num) {
    	return num * num;
    };
    
    result = square(7);
    console.log(result); // 49 출력
    上記の関数式(function expression)は、関数宣言(function declaration)とは異なり、シースは適用できません.
  • 番転送:宣言された場所を考慮せずに任意の場所で関数を使用できます.
  • したがって,関数宣言式のシースに過度に依存すると,コードメンテナンスが非常に困難になる可能性がある.シースを除いて、関数宣言式と関数式には大きな違いはありません.

    高次関数


    高次関数は、パラメータとして関数を受け入れ、関数として返される関数です.したがって、変数に関数を割り当てることができます.その後、関数で変数を返すことができます.
    (高次関数は関数をパラメータとして渡し、高次関数は関数自体を返しますが、変数が欠けています.)
    別の関数(呼び出し者)に渡されるパラメータ(パラメータ)の関数をコールバック関数(callback function)と呼ぶ.特定のタスクを完了するときに呼び出される関数.

    コールバック関数


    コールバック関数を渡す高次関数は、関数でコールバック関数を呼び出すことができます.関数(caller)は、条件に基づいてコールバック関数を実行するかどうかを決定することができる.呼び出さなくてもよいし、複数回実行してもよい.
    ex)パラメータとして関数を受け入れる関数(高次関数)
    function double(num) {
    	return num * 2;
    }
    
    function doubleNum(func, num) {
    	return func(num);
    }
    
    let result = doubleNum(double, 4);
    console.log(result) // 8;
    関数を返すとき
    function adder(added) {
    	return function(num) {
        	return num + added;
        };
    }
    
    let result = adder(5)(3);
    console.log(result); // 8 출력
    
    const add3 = adder(3); // adder가 함수에 변수 3을 저장해놓고
    let result2 = add3(2); // 저장된 변수 3을 added에 넣은 상태에서 function(num)에 2를 삽입한다.
    console.log(result2); // 따라서 결과값은 5가 나온다.
    ex)関数をパラメータとして受け取り,関数を返す.
    function double(num) {
    	return num * 2;
    }
    
    function doubleAdder(added, func) {
    	const doubled = func(added);
        return function (num) {
        	return num + doubled;
        };
    }
    
    doubleAdder(5, double)(3); // 13 출력
    // added에 5를 넣고, func에 double을 받아온다.
    // doubled = double(5)가 된다.
    // double return 값은 10이다.
    // return function(3)을 통해
    // return의 최종 결과값은 3 + 10 이다.
    
    const addTwice3 = doubleAdder(3, double);
    addTwice3(2); // 8 출력

    JavaScriptに組み込まれた高次関数


    配列に高次関数filterを内蔵することを学ぶ必要があります.
    フィルタベースの残りの高次関数
  • forEach
  • find
  • filter
  • map
  • reduce
  • sort
  • some
  • every
  • 抽象(抽象)を理解する必要がある.

    組み込みの高次関数について


    JavaScriptには様々な高次関数が存在します.いくつかの配列法は典型的な高次関数に相当する.最も基本的なフィルタを理解したら、次のステップに進みます.
    フィルタメソッドは、フィルタ条件を指定した関数と見なすことができます.
    ex)
    let arr = [1,2,3,4];
    
    arr.filter = function(arr, func){
    	const newArr = [];
        for(let i = 0; i < arr.length; i++){
        	if(func(arr[i]) === true){
            	newArr.push(this[i]);
            }
        }
        return newArr;
    };
    ex)実際の例を用いたfilter 1
    const isEven = function(num) {
    	return num % 2 === 0;
    };
    
    let arr = [1,2,3,4];
    let result = arr.filter(isEven);
    console.log(result); // [2,4];
    ex)実際の例を用いたfilter 2
    const isLetterFive = function(str){
    	return str.length <= 5;
    };
    
    arr = ["Hello", "Code", "States", "Happy", "Hacking"];
    let result = arr.filter(isLetterFive);
    console.log(result); // ["Hello", "Code", "Happy"] 출력

    Mapを知っておきましょう


    すべての要素に同じ動作を与えるすべての値を返します.
    行動は開発者が自分で作成しなければならない.(既存のシナリオは元のシナリオを保持します.)
    結果は、必要な動作に依存します.
    ex)Map例
    let arr = [1,2,3];
    
    let result = arr.map(function(ele){
    	return ele * 2
    });
    
    return result; // [2,4,6] 출력
    ex)map実績コード
    const movies = [
    	{
        	id: 1,
            bookType: 'Movie',
            title: 'Mission Impossible',
            subtitle: 'Powerful',
            createdAt: '2010-10-10',
            genre: 'Action',
            artist: 'Cruz',
            AverageScore: 9.55,
        },
        {
        	id: 2,
            // .. 이하 생략
        },
        // ... 이하 생략
    ];
    
    const findSubtitle = function(movies) {
    	return movies.subtitle;
    }
    
    const subtitles = movies.map(findSubtitle);
    // 각 영화들의 subtitle을 출력할 수 있다.

    filterについて説明しましょう。


    filterはすべての要素を返し、私が望む値だけをフィルタします.
    コードは開発者が作成し、関数で作成し、パラメータとして受信する必要があります.
    既存のシナリオを保持します.
    結果は、必要なフィルタによって異なります.
    ex)filter例
    let arr = [1,2,3];
    
    let result = arr.filter(function(ele){
    	return ele % 2 === 0
    }); 
    
    // 1,3 출력
    ex)filter実績
    const movies = [
    	{
        	id: 1,
            Type: 'movies',
            title: 'Mission Impossible',
            subtitle: 'Festival',
            createdAt: '2010-10-10',
            genre: 'Action',
            artist: 'Cruz',
            averageScore: 9.55,
        }
        {
        	id: 2,
            // ... 이하 생략
        },
        // ... 이하 생략
    ];
    
    const isCreatedAt2010 = function(movies){
    	const fullYear = new Data(movies.createdAt).getFullYear();
        return fullYear === 2010;
    };
    
    const filteredMovies = movies.filter(isCreatedAt2010);
    // 2010년에 만들어진 영화들 출력

    reduceを理解してください。


    reduceは配列を値にします.
    reduceは初期値を設定できます.(設定されていない場合は、アレイの最初の値が初期値になります.)
    初期値は累積値に格納されます.
    この値は、後続のアレイの最後に保存されます.(保存すると、この値は開発者の動作に応じて変更されます.)
    最後に、累積値の値が返されます.
    ex)reduce初期値設定がない例
    let arr = [1,2,3];
    
    let result = arr.reduce(function(acc, cur, idx) {
    	acc += cur;
        return acc;
    });
    
    result; // 6
    ex)reduce初期値設定の例
    let arr = [1,2,3];
    let result = arr.reduce(function(acc, cur, idx){
    	acc += cur;
        return acc;
    }, 1); // 1로 초기값을 설정
    
    result; // 결과는 7을 출력한다.
    ex)reduce実績コード
    const movies = [
    	{
        	id: 1,
            Type: 'movies',
            title: 'Mission Impossible',
            subtitle: 'Festival',
            createdAt: '2010-10-10',
            genre: 'Action',
            artist: 'Cruz',
            averageScore: 9.55,
        }
        {
        	id: 2,
            // ... 이하 생략
        },
        // ... 이하 생략
    ];
    
    const scoreReducer = function(sum, movies) {
    	return sum + movies.averageScore;
    };
    
    let initialValue = 0;
    const moviesAvgScore = movies.reduce(scoreReducer, initialValue) / movies.length;

    reduceの独特な使い方


    配列を文字列として出力できます.
    function joinName(resultStr, user) {
        resultStr = resultStr + user.name + ', ';
        return resultStr;
    }
    
    let users = [
        { name: 'KJ', age: 40 },
        { name: 'SJ', age: 30 },
        { name: 'SH', age: 50 }
    ];
    
    console.log(users.reduce(joinName, '')); // KJ, SJ, SH, 출력

    配列をオブジェクトとする

    function makeAddressBook(addressBook, user){
        let firstLetter = user.name[0];
    
        if(firstLetter in addressBook){
            addressBook[firstLetter].push(user); // firstLetter 가 있는 경우
        } else {
            addressBook[firstLetter] = []; // firstLetter 가 없는 경우
            addressBook[firstLetter].push(user);
        }
    
        return addressBook;
    }
    
    let users = [
        { name: 'KJ', age: 40},
        { name: 'SJ', age: 30},
        { name: 'UH', age: 50}
    ];
    
    console.log(users.reduce(makeAddressBook, {}));
    //{
    //    K: [ { name: 'KJ', age: 40} ],
    //    S: [ { name: 'SJ', age: 30} ],
    //    U: [ { name: 'UH', age: 50} ],
    //} 출력

    なぜ高次関数を使うのか


    これは抽象的だからです.抽象化とは、いくつかの複雑なコンテンツをコアのみを抽出する状態に圧縮することである.たとえば、1から5を加算すると、どのようなプロセスで得られた値が15なのか分かりませんが、結果値を知ることができます.
    ex)
    function sum(num1, num2){
    	return num1 + num2;
    }
    const result = sum(2, 5);
    console.log(result); // 7 출력
    これらの問題はコンピュータ抽象によって解決できる.
    抽象化=生産性の向上
    関数によって得られる抽象を1つのレベル、すなわち二次関数に高めた.
    高次関数は、この抽象レベルを思考の抽象レベルに引き上げます.
  • 値レベルの抽象:
  • レベルは値のみを受け入れます(値)
  • 事故の抽象:
  • レベル、関数の伝達と処理に使用
    抽象度が上がるにつれて、仕事の効率も上がる.
    const data = [
        {
            gender: 'male',
            age: 24,
        },
        {
            gender: 'male',
            age: 25,
        },
        {
            gender: 'female',
            age: 27,
        },
        {
            gender: 'female',
            age: 22,
        },
        {
            gender: 'male',
            age: 29,
        },
    ];
    
    // 남자만 있는 배열을 만들어보자
    function getAverageOfMaleAtOnce(data) {
        const onlyMales = data.filter(function (el) {
            return el.gender === 'male';
        });
    
        const numOfMales = onlyMales.length;
    
        const onlyMaleAges = onlyMales.map(function (el) {
            return el.age;
        }); // 오직 남라고 구성된 배열에서 나이를 배열로 리턴할 수 있다.
    
        const sumOfAges = onlyMales.reduce(function(acc, cur){
           acc += cur
            return acc;
        }, 0); // 오직 남자들의 나이만을 더했을 때
    
        return sumOfAges / numOfMales;
        // 남자들의 평균 나이
    }
    必要な操作を順番に実行できます.男性の平均年齢を求める場合、様々な方法で結果を求めることができます.

    高次関数の定理


    高次関数の種類
  • Array.prototype.find(検索要素)
  • Array.prototype.reduce(累積、初期値0)
  • Array.prototype.filter(条件でフィルタ)