一道面試題引發(fā)的思考

起因

今天跟一位程序員朋友日常聊天,聊到了一道面試題:

請用JS實現(xiàn)一個函數(shù)InsertItemToArray先鱼,
函數(shù)接受三個參數(shù):要插入元素的數(shù)組奸鬓、要插入的新元素、新元素所在的位置(arr, item, index)宏多,
往原數(shù)組arr的index位置插入一個新的元素item澡罚,index之后的元素索引依次后移,并返回插入新元素后的新數(shù)組更胖。

要求:不允許用splice,slice。

這道題讀完題目后巢音,慣性思路就是寫一個for循環(huán),比如:

const InsetItemToArray = (arr, item, index) => {
  const resultArr = [];
  for(let i = 0; i < arr.length + 1; i++){
    if (i < index){
      resultArr.push(arr[i]);
    } else if (i > index) {
      resultArr.push(arr[i - 1]);
    } else {
      resultArr[i] = item;
    }
  }
  return resultArr;
}

InsetItemToArray([1,2,3], 'a', 1);

// [1, 'a', 2, 3]

或者換個思路:

const InsetItemToArray = (arr, item, index) => {
  const resultArr = [...arr];
  for(let i = arr.length; i > index; i--){
    resultArr[i] = arr[i - 1];
  }
  resultArr[index] = item;
  return resultArr;
}

InsetItemToArray([1,2,3], 'b', 1);

// [1, 'b', 2, 3]

以上都是比較常用且不用花太多思考時間的寫法。

轉(zhuǎn)折

這時候突然覺得账锹,這道題其實可以用解構(gòu)賦值的模式匹配來實現(xiàn)坷襟。

我們知道婴程,es6的解構(gòu)賦值是可以這樣寫的:

const arr = [1, 2, 3, 4, 5];
const [ , ,...resultArr] = arr;

// resultArr =>  [3, 4, 5]

那我們可以把返回結(jié)果看成是兩個部分:

  • 第一部分是headArr档叔,包含原數(shù)組arr中索引值小于index的元素和即將插入的新元素item
  • 第二部分是footArr蒸绩,包含原數(shù)組arr中索引值大于或等于index的元素

最后將兩個部分拼在一起,即是要返回的新數(shù)組了传蹈。

我們先來看怎么得到footArr步藕。

// 錯誤示例
const GetFootArr = (arr, item, index) => {
    const placeArr = new Array(index);
    const [...placeArr, ...footArr] = arr;
    return footArr;
}
// 控制臺拋出一個錯誤:Uncaught SyntaxError: Rest element must be last element

奇怪了,讓我們對比一下結(jié)果:

// 正常解構(gòu)
const arr = [1, 2, 3, 4, 5];
const [ , ,...resultArr] = arr;

// resultArr =>  [3, 4, 5]


// 報錯
const arr = [1, 2, 3, 4, 5];
const placeArr = new Array(2);
const [...placeArr, ...resultArr] = arr;

// Uncaught SyntaxError: Rest element must be last element

這時候打印placeArr

console.log(placeArr);
// [empty × 2]

打印[...palceArr]

console.log([...placeArr]);
// [undefined, undefined]

我們發(fā)現(xiàn)原本用來占位的empty都變成了undefined沾歪。

結(jié)論

數(shù)組的空位指灾搏,數(shù)組的某一個位置沒有任何值立润。比如,Array構(gòu)造函數(shù)返回的數(shù)組都是空位蕾域。

就像剛才打印placeArr得到的結(jié)果都是empty一樣。

但是要注意:

空位并不是undefined搁骑,一個位置的值等于undefined又固,依然是有值的⊙笾唬空位是沒有任何值妒茬,in運算符可以說明這一點团赁。

0 in [undefined, undefined, undefined] // true
0 in [, , ,] // false

上面代碼說明,第一個數(shù)組的 0 號位置是有值的析蝴,第二個數(shù)組的 0 號位置沒有值吞滞。

擴展運算符(...)是會將空位轉(zhuǎn)為undefined。

[...['a',,'b']]
// [ "a", undefined, "b" ]

除了擴展運算符,entries()谭确、keys()问顷、values()出皇、find()findIndex()都會將空位處理成undefined纱注。

// entries()
[...[,'a'].entries()] // [[0,undefined], [1,"a"]]

// keys()
[...[,'a'].keys()] // [0,1]

// values()
[...[,'a'].values()] // [undefined,"a"]

// find()
[,'a'].find(x => true) // undefined

// findIndex()
[,'a'].findIndex(x => true) // 0

而數(shù)組解構(gòu)賦值的模式匹配,并不能匹配undefined作為變量名。所以placeArr就不能被正常的賦值。

關(guān)于數(shù)組空位的解釋扎谎,可以參考阮一峰老師的ECMAScript 6 入門 - 數(shù)組的擴展
這里不做多的引申觅够。

PS

既然解構(gòu)賦值的思路行不通廷粒,但是我們?nèi)耘f可以按照headArrfootArr的思路來解這道題嗤放,只需換一種寫法岳服。

比如:

const InsetItemToArray = (arr, item, index) => {
  const headArr = arr.filter((_, i) => i < index);
  const footArr = arr.filter((_, i) => i >= index);
  return [ ...headArr, item, ...footArr];
}

InsetItemToArray([1,2,3], 'c', 2);

// [1, 2, 'c', 3]

這樣一來我們就得到了正確的結(jié)果了文兑。

完籍铁。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末增显,一起剝皮案震驚了整個濱河市脐帝,隨后出現(xiàn)的幾起案子糖权,更是在濱河造成了極大的恐慌旱易,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浸船,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機在辆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門匆篓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寇窑,“玉大人先慷,你說我怎么就攤上這事谨设。” “怎么了赴肚?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵誉券,是天一觀的道長。 經(jīng)常有香客問我踊跟,道長鸥诽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任拳昌,我火速辦了婚禮钠龙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘沈矿。我一直安慰自己咬腋,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布溜徙。 她就那樣靜靜地躺著犀填,像睡著了一般。 火紅的嫁衣襯著肌膚如雪图贸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天偿洁,我揣著相機與錄音沟优,去河邊找鬼。 笑死宾肺,一個胖子當(dāng)著我的面吹牛侵俗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播增拥,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼寻歧,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了猾封?” 一聲冷哼從身側(cè)響起弟晚,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤卿城,失蹤者是張志新(化名)和其女友劉穎铅搓,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體多望,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡怀偷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年播玖,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片维蒙。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡颅痊,死狀恐怖殖熟,靈堂內(nèi)的尸體忽然破棺而出菱属,到底是詐尸還是另有隱情恋捆,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布膜毁,位于F島的核電站,受9級特大地震影響瘟滨,放射性物質(zhì)發(fā)生泄漏能颁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一败玉、第九天 我趴在偏房一處隱蔽的房頂上張望镜硕。 院中可真熱鬧,春花似錦血淌、人聲如沸财剖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽咪橙。三九已至栓袖,卻和暖如春店诗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背捧弃。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工违霞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瞬场,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓眼五,卻偏偏與公主長得像彤灶,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子诵姜,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)自:產(chǎn)品經(jīng)理從0到1 之前面了幾家公司棚唆,感受到了不同產(chǎn)品總監(jiān)迥異的面試風(fēng)格心例,有聊實的,有聊虛的契邀,有單聊業(yè)務(wù)的失暴,也...
    萌丸1014閱讀 404評論 0 3
  • 搜狐面試題:有12個球,外形都一樣古戴,其中有一個質(zhì)量和其他的不一樣矩肩,給你一架天平,請問最少稱幾次可以把那個不同的球找...
    junhey閱讀 542評論 0 0
  • 第2章 基本語法 2.1 概述 基本句法和變量 語句 JavaScript程序的執(zhí)行單位為行(line)叉袍,也就是一...
    悟名先生閱讀 4,148評論 0 13
  • 在送南瓜去托班前一周的某個晚上润文,我很焦慮姐呐,非常焦慮曙砂,焦慮的睡不著覺。 南瓜兩歲零九個月鸠澈,一直是姥姥和奶奶輪流帶砖织。今...
    個人成長教練周育楠閱讀 391評論 1 3
  • 把一棵黃金的銀杏 劈成一扇門 把路的終點與蝴蝶相連 拾起洞穴的壁畫 放入你胳膊 在火的背面 雕刻你的臉 于大雪中 ...
    我是不是蝎大人閱讀 208評論 0 0