前言
昨天聯調一個頁面,看着就一個頁面,接口倒是不少。
熱點問題配置測試聯調完成(同步異步接口共11個) 1.配置新增 2.配置編輯 3.配置刪除 4.熱點問題新增 5.熱點問題編輯 6.熱點問題刪除 7.熱點問題上移 8.熱點問題下移 9.熱點問題保存 10.熱點問題校驗 11.熱點問題列表
下圖這一塊是最麻煩的,調用的其他部分的組件,為了能復用,聯調了很久。
之前封裝的組件每一個動作是調接口的異步行為,此時改成同步的,最后保存一起提交。
那么在同步處理的時候,用到了很多數組的增刪改,index索引值的變更。
下面,我首先總結一下數組處理的所有方法,再把在此處會用到的方法貼出來。
一.增加元素
1.push():push可接收任意數量的參數,把它們逐個添加至數組末尾,並且可以返回修改后數組的長度。
var sports = ['soccer', 'baseball']; var total = sports.push('football', 'swimming'); console.log(sports); // ['soccer', 'baseball', 'football', 'swimming'] console.log(total); // 4
2.unshift() :與push()類似,也可接收任意數量的參數,只不過是將參數逐個添加至數組最前面而已,同樣返回新數組長度。
const array1 = [1, 2, 3];
console.log(array1.unshift(4, 5));
// expected output: 5
console.log(array1);
// expected output: Array [4, 5, 1, 2, 3]
3.concat() :該方法與push()方法有點類似,同樣是將元素添加至數組末尾,只不過這個數組已經不是原來的那個數組了,而是其副本,所以concat()操作數組后會返回一個新的數組。
特性:
-
- 不傳參數,返回當前數組副本
- 傳遞非數組參數,這些參數就會被直接添加到結果數組的末尾
- 傳遞數組參數,將數組每一個元素,添加新的數組中
const array1 = ['a', 'b', 'c']; const array2 = ['d', 'e', 'f']; console.log(array1.concat(array2)); // expected output: Array ["a", "b", "c", "d", "e", "f"]
4.splice(): 功能很強大,划重點
前面的三個方法都具有很大局限性,因為不是添加到數組前就是數組后,而splice()它非常靈活,它可以添加元素到數組的任意位置。
它除了可以添加元素之外還具有刪除和替換元素的功能。
splice()可以向數組指定位置添加任意數量的元素。
需要傳入至少3個參數:splice(a, b, c, d, ......)
-
- 1、a 起始元素的位置
- 2、b 要刪除的元素個數,從起始元素開始算
- 3、c后面的是要插入的元素,可以是數組
總結一下,原理就是,在規定的起始位置a,刪除b個,如果后面需要塞進去新元素就加到cd...的位置,如果不加就是刪除了,splice實質上是通過刪除元素來實現插入、刪除、替換的
4.1 splice 刪除
寫法
array.splice(index,n);
參數含義
index:數組中需要刪除數據的起始位置;
n:需要刪除的元素,數據的個數;
4.2 splice 插入
寫法
array.splice(index,0,data1,data2,....);
參數
index:數組中需要插入數據的起始位置;
0:刪除的個數為0;
data1,data2:需要插入的元素,用逗號隔開
4.3 splice 替換
寫法
array.splice(index,n,data1,data2,......);
參數
index:需要替換的元素的起始位置;
n:需要替換的元素的個數,實質是刪除;
data1,data2:需要插入元素,用逗號隔開;
二、刪除元素
1.pop() :與push()方法配合使用可以構成后進先出的棧,該方法可從數組末尾刪除最后一項並返回該項
const plants = ['broccoli', 'cauliflower', 'cabbage', 'kale', 'tomato']; console.log(plants.pop()); // expected output: "tomato" console.log(plants); // expected output: Array ["broccoli", "cauliflower", "cabbage", "kale"] plants.pop(); console.log(plants); // expected output: Array ["broccoli", "cauliflower", "cabbage"]
2.shift(): 與push()方法配合使用可以構成先進先出的隊列,該方法可刪除數組第一項並返回該項。
const array1 = [1, 2, 3]; const firstElement = array1.shift(); console.log(array1); // expected output: Array [2, 3] console.log(firstElement); // expected output: 1
3.slice(): 該方法同concat()一樣是返回一個新數組,不會影響原數組,只不過slice()是用來裁剪數組的,返回裁剪下來的數組。
slice()方法可以接受一或兩個參數,
1、一個參數,返回從該參數指定位置開始到當前數組末尾的所有項。
2、兩個參數,返回起始和結束位置之間的項,但不包括結束位置的項。
const animals = ['ant', 'bison', 'camel', 'duck', 'elephant']; console.log(animals.slice(2)); // expected output: Array ["camel", "duck", "elephant"] console.log(animals.slice(2, 4)); // expected output: Array ["camel", "duck"] console.log(animals.slice(1, 5)); // expected output: Array ["bison", "camel", "duck", "elephant"]
4、splice(): 它除了可以添加元素之外還具有刪除和替換元素的功能。 詳細看以上例子
三、查找元素
indexOf() 和 lastIndexOf()
這兩個方法都接收兩個參數:
1、要查找的項
2、表示查找起點位置的索引。(可選的)
indexOf() 從數組的開頭(位置0)開始向后查找。
lastIndexOf() 從數組的末尾開始向前查找。
兩個方法,當找不到該元素時,都返回 -1
var arr = [1,2,3,4,5,2]; var index = arr.indexOf(2); console.log(index); // 1 index = arr.indexOf(2, 0); console.log(index); // 1 index = arr.indexOf(2, 2); console.log(index); // 5 index = arr.indexOf(6); console.log(index); // -1
其它方法:
1.join():該方法用來將數組轉換為字符串,不改變原數組,返回轉換后的字符串
const elements = ['Fire', 'Air', 'Water']; console.log(elements.join()); // expected output: "Fire,Air,Water" console.log(elements.join('')); // expected output: "FireAirWater" console.log(elements.join('-')); // expected output: "Fire-Air-Water"
2.sort(): 按ascii碼排序,改變原數組,返回排序后的數組
const months = ['March', 'Jan', 'Feb', 'Dec']; months.sort(); console.log(months); // expected output: Array ["Dec", "Feb", "Jan", "March"] const array1 = [1, 30, 4, 21, 100000]; array1.sort(); console.log(array1); // expected output: Array [1, 100000, 21, 30, 4]
3.reverse() :用於顛倒數組中元素的順序。返回的是顛倒后的數組,會改變原數組。
const array1 = ['one', 'two', 'three']; console.log('array1:', array1); // expected output: "array1:" Array ["one", "two", "three"] const reversed = array1.reverse(); console.log('reversed:', reversed); // expected output: "reversed:" Array ["three", "two", "one"] /* Careful: reverse is destructive. It also changes the original array */ console.log('array1:', array1); // expected output: "array1:" Array ["three", "two", "one"]
4.filter():返回數組中滿足條件的元素組成的新數組,原數組不變(篩選,過濾)
const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present']; const result = words.filter(word => word.length > 6); console.log(result); // expected output: Array ["exuberant", "destruction", "present"]
5.map() :map() 方法來根據需求格式化原數組,返回格式化后的數組。原數組不變。可以傳入三個值,分別是(當前元素,索引index,map的原數組)
var arr = [1,2,3,4,5,2]; var arr2 = arr.map(function(current, index, array){ console.log("當前元素current="+current + "索引index="+index +"數組array="+array) return "$"+current }) console.log(arr) //[1, 2, 3, 4, 5, 2] console.log(arr2) //["$1", "$2", "$3", "$4", "$5", "$2"]
6.every() :對數組的每一項都運行給定的函數,若每一項都返回 ture,則返回 true($$)
const isBelowThreshold = (currentValue) => currentValue < 40; const array1 = [1, 30, 39, 29, 10, 13]; console.log(array1.every(isBelowThreshold)); // expected output: true
7.some():對數組的每一項都運行給定的函數,若存在一項或多項返回 ture,否則返回 false(||)
const array = [1, 2, 3, 4, 5]; // checks whether an element is even const even = (element) => element % 2 === 0; console.log(array.some(even)); // expected output: true
8.forEach() :遍歷整個數組,不中斷,可以傳入三個值,分別是(當前元素,索引index,原數組)
const array1 = ['a', 'b', 'c']; array1.forEach(element => console.log(element)); // expected output: "a" // expected output: "b" // expected output: "c"
forEach和map很相似,很多地方用兩個其中一種都行
相同點:
- 都是只能遍歷數組
- 都有三個返回值(當前元素,索引index,原數組)
- 都是循環遍歷數組每一項
區別是:
map,有返回值,可以return出來
forEach,沒有返回值。forEach()返回值是undefined,不可以鏈式調用。
沒有辦法終止或者跳出forEach()循環,除非拋出異常,所以想執行一個數組是否滿足什么條件,返回布爾值,可以用一般的for循環實現,或者用Array.every()或者Array.some();
關於以上區別的筆試題
["1", "2", "3"].map(parseInt); //結果 [1, NaN, NaN]
如果想得到[1, 2,3]應該這么做
function returnInt(element){ return parseInt(element,10); } ["1", "2", "3"].map(returnInt);
這主要是因為 parseInt()默認有兩個參數,第二個參數是進制數。當parsrInt沒有傳入參數的時候,而map()中的回調函數時候,會給它傳三個參數,第二個參數就是索引,明顯不正確,所以返回NaN了。
另,寫map需要注意的點:
寫到這里,發現這篇文章好長啊,已經寫了一個小時了。不知道為什么博客園不能只用一種代碼引入樣式,兩種弄的眼花繚亂,你們將就看吧。
下面貼一下實現最上面項目功能的store代碼(技術棧react+mobx)
// 新增一個空的熱點問題 @action addHotItem = (obj) => { const { handledHotTopicContext } = this.currentItem; const { list } = handledHotTopicContext this.currentItem = { ...this.currentItem, handledHotTopicContext: { ...handledHotTopicContext, list: [...list, obj], selectedItem: null } }; } // 保存一個熱點問題(新增或修改) @action saveHotItem = (param, index) => { const { id } = param; const { handledHotTopicContext } = this.currentItem; const { list } = handledHotTopicContext // 編輯 if (id !== undefined) { list.splice(id, 1, param); this.currentItem = { ...this.currentItem, handledHotTopicContext: { ...handledHotTopicContext, list: [...list], selectedItem: null } };
// 新增 } else { const leg = list.length - 1 const { name } = param const addObj = { id: leg, name: name } list.splice(leg, 1, addObj); // list.push(addObj) this.currentItem = { ...this.currentItem, handledHotTopicContext: { ...handledHotTopicContext, list: [...list], selectedItem: null } }; } } // 刪除一個熱點問題 @action delHotItem = (param) => { const { id } = param; const { handledHotTopicContext } = this.currentItem; const { list } = handledHotTopicContext list.splice(id, 1); this.currentItem = { ...this.currentItem, handledHotTopicContext: { ...handledHotTopicContext, list: [...list], selectedItem: null } }; } // 上移下移一個熱點問題 @action moveHotItem = (item, key) => { let temp = null; const { id } = item; let index = 0; const { handledHotTopicContext } = this.currentItem; const { list } = handledHotTopicContext index = list.findIndex(ele => ele.id === item.id); if (key === 'up') { temp = { ...list[index - 1] }; list[index - 1] = { ...list[index] }; list[index] = temp; this.currentItem = { ...this.currentItem, handledHotTopicContext: { ...handledHotTopicContext, list: [...list], selectedItem: null } }; } else { temp = { ...list[index + 1] }; list[index + 1] = { ...list[index] }; list[index] = temp; this.currentItem = { ...this.currentItem, handledHotTopicContext: { ...handledHotTopicContext, list: [...list], selectedItem: null } }; } }