欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript??际謱戭}之柯里化與數(shù)組扁平化的實現(xiàn)

 更新時間:2023年12月29日 14:00:36   作者:慕仲卿  
這篇文章主要為大家詳細介紹了JavaScript??际謱戭}中柯里化與數(shù)組扁平化、數(shù)組去重的實現(xiàn),文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習一下

以下題目來自其它博客,但是問題的答案都是根據(jù)筆者自己的理解做出的。如果你最近想要換工作或者鞏固一下自己的前端知識基礎(chǔ),不妨和我一起參與到每日刷題的過程中來,如何?

第四天要刷的手寫題如下:

  • 手寫一個函數(shù),實現(xiàn)柯里化功能
  • 手寫一個函數(shù),實現(xiàn)數(shù)組扁平化的功能
  • 手寫一個函數(shù),實現(xiàn)數(shù)組去重的功能

下面是我自己寫的答案:

1. 手寫一個函數(shù),實現(xiàn)柯里化功能

分析: 柯里化的本質(zhì)是**收集到一定數(shù)量的參數(shù)(稱為生產(chǎn)資料更為合適)**之后才去執(zhí)行既定的函數(shù),如果參數(shù)的數(shù)目小于既定函數(shù)執(zhí)行所需要的個數(shù)則不執(zhí)行,而是繼續(xù)收集參數(shù)。

如果用代碼來表示,可以設(shè)既定函數(shù)為f,柯里化之后映射成為函數(shù)g,g在執(zhí)行的時候會對積累到的參數(shù)的數(shù)目進行判斷,如果數(shù)目是足夠的,則返回f的執(zhí)行結(jié)果(相當于執(zhí)行了f),如果參數(shù)的數(shù)目不夠,則將此次調(diào)用傳入的參數(shù)累積起來,然后返回函數(shù)g',等待下一次調(diào)用。**返回的g'函數(shù)和g具有相同的德行。

根據(jù)上面的分析,首先需要一個私有域存儲已經(jīng)收集到了的參數(shù),這就需要用到閉包了;而執(zhí)行既定函數(shù)的參數(shù)數(shù)目可以直接從既定函數(shù)上獲?。?code>f.length表示函數(shù)需要的形參數(shù)目。

現(xiàn)在嘗試性的寫一下:

function _G (f) {
    if(typeof f !== "function") throw new Error('f must be a function!');
    return function (...rest) {
        const currentParams = [...rest];
        const currentLength = currentParams.length;
        if(currentLength >= f.length) return f.apply(this, currentParams);
        // return _G(f); ???
    }
}

這里無法處理參數(shù)不夠的時候如何返回一個g'的問題。上面分析到g'g性質(zhì)相同,所以g'g都是由_G產(chǎn)生的,所以問題出在_G沒有設(shè)計好,一個參數(shù)根本無法區(qū)分g'g。

于是,需要增加一個形參,表示目前g類已經(jīng)收集到的參數(shù):

function _G (f, alreadyCollectedParams = []) {
    if(typeof f !== "function") throw new Error('f must be a function!');
    return function (...rest) {
        const currentParams = [...alreadyCollectedParams, ...rest];
        const currentLength = currentParams.length;
        if(currentLength >= f.length) return f.apply(this, currentParams);
        return _G(f, currentParams);
    }
}

function add (a,b,c) {
    return a+b+c;
}

const c_add = _G(add);

console.log(c_add(1)(2)(3)); // 6
console.log(c_add(1, 2)(3)); // 6
console.log(c_add(1)(2, 3)); // 6
console.log(c_add(1, 2, 3)); // 6

使用ES6創(chuàng)建極簡版:

// 極簡版
// const __G = (f, alreadyCollectedParams = []) => (...rest) => [...alreadyCollectedParams, ...rest].length >= f.length ? f.apply(this, [...alreadyCollectedParams, ...rest]) : _G(f, currentParams);
const __G = (f, a = []) => (...r) => (_ = [...a, ...r], _.length >= f.length ? f.apply(this, _) : __G(f, _));

2. 手寫一個函數(shù),實現(xiàn)數(shù)組扁平化的功能

所謂數(shù)組扁平化指的就是如果數(shù)組中的元素依然是數(shù)組,則將內(nèi)嵌數(shù)組中的元素拿出來直接放到上層數(shù)組中即可。

2.1 方法一:forEach 和 push

一個最基本的想法就是,創(chuàng)建一個_flat方法用來遍歷這個數(shù)組,然后再在歷過程中對數(shù)組中的每一個元素進行判斷;如果元素的類型不是數(shù)組則直接push到記錄數(shù)組中去,如果元素的類型是數(shù)組,則對此內(nèi)嵌數(shù)組遞歸調(diào)用_flat; 這樣相當于對任何一級的數(shù)組的每一個元素都進行了遍歷,也就是使用深度遍歷算法。

function _flat (targetArray, container = []) {
    if(!Array.isArray(targetArray)) return container;
    targetArray.forEach(
        item => {
            if (!Array.isArray(item)) {
                container.push(item);
            } else {
                _flat(item, container);
            }
        }
    )
    return container;
}

const rst = _flat([[[[[[1],2],3],4],5,6],7]);
// const rst = _flat('[[[[[[1],2],3],4],5,6],7]');
console.log('rst: ', rst);

2.2 方法二: Array.prototype.flat

ES6中Array的原型上增加了一個名為flat的方法,其作用就是將嵌套數(shù)組拆包一次;顯然沒拆一次,整個數(shù)組的元素數(shù)目是(非嚴格)單調(diào)遞增的;根據(jù)這個性質(zhì),使用while循環(huán)一直對其拆包,直到某兩次拆完之后元素數(shù)目相等.

function _flat2 (targetArray) {
    if(!Array.isArray(targetArray)) return [];
    let _loop = targetArray;
    while(1){
        const beforeFlat = _loop.length;
        const _Arr = _loop.flat();
        const afterFlat = _Arr.length;
        if(beforeFlat == afterFlat) return _Arr;
        _loop = _Arr;
    }
}

const rst2 = _flat2([[[[[[1],2],3],4],5,6],7]);
console.log('rst2: ', rst2);

2.3 方法三: findIndex 和 splice

如果在遍歷之前就知道為內(nèi)嵌數(shù)組元素的序列號就好了,這樣只需要到對應(yīng)的位置上找到并將其展開就可以了;這個過程一直持續(xù)到原數(shù)組中再也找不到內(nèi)嵌數(shù)組元素就停止下來。 這種方法是在原來的數(shù)組上直接操作的,會改變原數(shù)組的內(nèi)容

function _flat3 (targetArray) {
    if(!Array.isArray(targetArray)) return [];
    while(1){
        const arrItemIndex = targetArray.findIndex(
            item => Array.isArray(item)
        )
        if(arrItemIndex === -1) return targetArray;
        targetArray.splice(arrItemIndex, 1, ...targetArray[arrItemIndex]);
    }
}

const rst3 = _flat3([[[[[[1],2],3],4],5,6],7]);
console.log('rst3: ', rst3);

2.4 方法四: stack

  • 使用棧這種數(shù)據(jù)結(jié)果,其本質(zhì)上和遞歸的算法是完全相同的;但是使用棧來理解的話,會極大的減小心智負擔
  • 使用兩個棧a和b,開始的時候?qū)⒃紨?shù)組整體放入到a棧中去,此時b棧為空;
  • 然后對a棧執(zhí)行下面的動作,直到a棧為空:
  • 彈棧->判斷彈出元素是否是數(shù)組,如果不是,則進入棧b,如果是則拆包一次,再重新進入棧a
  • 最后輸出棧b即可
function _flat4 (targetArray) {
    if(!Array.isArray(targetArray)) return [];
    // 原始數(shù)組全部入a棧
    const a = [...targetArray];
    const b = [];
    while(a.length){
        const _tmp = a.pop();
        if (Array.isArray(_tmp)) {
            a.push(..._tmp); // 這里不要遍歷push,顯得很low,a.concat(_tmp)也可
        } else {
            b.push(_tmp);
        }
    }
    return b;
}

const rst4 = _flat4([[[[[[1],2],3],4],5,6],7]);
console.log('rst4: ', rst4);

3. 手寫一個函數(shù),實現(xiàn)數(shù)組去重的功能

就是字面意思,不難理解!

3.1 利用set對象的機制,將數(shù)組先變成set然后將set再變成數(shù)組

// 一行搞定
const unique = (array) => [...newSet(array)];

3.2 繼續(xù)使用兩個棧

  • 繼續(xù)使用兩個棧a和b,a執(zhí)行下面的動作直到空棧
  • 彈棧->判斷彈出元素在b棧中是否存在,如果存在丟棄,如果不存在進入棧b
const unique2 = (array) => {
    if(!Array.isArray(array)) return [];
    const a = [...array];
    const b = [];
    while(a.length){
        const item = a.pop();
        // const item = a.shift();
        if(b.includes(item)) continue;
        b.push(item);
    }
    return b;
}

可以將pop改成shift有利于保證順序

3.3 3.2改進版本

對上面的實現(xiàn)方式進行優(yōu)化,因為數(shù)組通過內(nèi)容查詢元素的效率實在是太低了,所以將b從棧改成字典,字典一般是使用hash表實現(xiàn)的,在根據(jù)查找方面比數(shù)組要快

const unique3 = (array) => {
    if(!Array.isArray(array)) return [];
    const a = [...array];
    const b = new Map();
    while(a.length){
        const item = a.pop();
        // const item = a.shift();
        b.set(item,1);
    }
    return [...b.keys()];
}

console.log(unique3([1,1,1,1,2,3,4,345,345]));

到此這篇關(guān)于JavaScript常考手寫題之柯里化與數(shù)組扁平化的實現(xiàn)的文章就介紹到這了,更多相關(guān)JavaScript手寫題內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論