最近在CodeWars上作了一道題目,嗯,我這個渣渣沒有作出來,而後看了別人的解決方案,Map???javascript
是時候學習一下ES6的Map了。。。。。java
如下是原題:(https://www.codewars.com/kata...)git
Description:es6
You have a positive number n consisting of digits. You can do at most one operation: Choosing the index of a digit in the number, remove this digit at that index and insert it back to another place in the number.數組
Doing so, find the smallest number you can get.數據結構
Task:函數
Return an array or a tuple depending on the language (see "Your Test Cases" Haskell) with學習
1) the smallest number you got
2) the index i of the digit d you took, i as small as possible
3) the index j (as small as possible) where you insert this digit d to have the smallest number.this
Example:prototype
smallest(261235) --> [126235, 2, 0]
126235 is the smallest number gotten by taking 1 at index 2 and putting it at index 0
smallest(209917) --> [29917, 0, 1]
[29917, 1, 0] could be a solution too but index i
in [29917, 1, 0] is greater than
index i
in [29917, 0, 1].
29917 is the smallest number gotten by taking 2 at index 0 and putting it at index 1 which gave 029917 which is the number 29917.
smallest(1000000) --> [1, 0, 6]
如下就是某人的解決方案:
Array.prototype.move = function(from, to) { this.splice(to, 0, this.splice(from, 1)[0]); return this; }; function smallest(n) { let iter = `${n}`.length, res = new Map(); //使用ES6的模板字符串還有Map數據結構 for (let i = 0; i < iter; i++) { for (let j = 0; j < iter; j++) { let number = `${n}`.split('').move(i, j).join(''); //排列組合???哈哈 if (!res.has(+number)) res.set(+number, [i, j]); //添加鍵值對到Map } } let min = Math.min(...res.keys()); //res.keys()獲得鍵名的遍歷器,而後擴展運算符轉化爲數組,而後最小的number return [min, ...res.get(min)]; //res.get(min)獲得對應鍵名的鍵值 }
如下內容來自大神博客:阮一峯ES6入門書籍
JavaScript的對象(Object),本質上是鍵值對的集合(Hash結構),可是傳統上只能用字符串看成鍵。這給它的使用帶來了很大的限制。
Map數據結構相似於對象,也是鍵值對的集合,可是鍵的範圍不限於字符串,各類類型的值均可以做爲鍵。若是你須要「鍵值對」的數據結構,Map比Object更合適。
var m = new Map(); var o = {p: 'hello world'}; m.set(0, 'connect'); m.get(0); //'connect' m.has(0); //true m.delete(o); //true m.has(o); //false
size()
:返回Map結構的成員總數
操做方法
set(key, value)
:設置對應的鍵值,而後返回整個Map結構。若是key已經有值,則鍵值會被更新。
var m = new Map(); m.set("edition", 6) // 鍵是字符串 m.set(262, "standard") // 鍵是數值 m.set(undefined, "nah") // 鍵是undefined //set方法返回的是Map自己,所以能夠採用鏈式寫法。 let map = new Map() .set(1, 'a') .set(2, 'b') .set(3, 'c');
get(key)
:讀取key對應的鍵值,若是找不到key返回undefined
var m = new Map(); var hello = function() { console.log("hello"); } m.set(hello, "Hello ES6!") // 鍵是函數 m.get(hello) // Hello ES6!
has(key)
:返回一個布爾值,表示某個鍵是否在Map數據結構中。
delete(key)
:刪除某個鍵,成功返回true;刪除失敗返回false。
clear()
:刪除全部成員,沒有返回值。
遍歷方法
keys()
:返回鍵名的遍歷器
values()
:返回鍵值的遍歷器
entries()
:返回全部成員的遍歷器
forEach()
:遍歷Map的全部成員
let map = new Map([ ['F', 'no'], ['T', 'yes'], ]); for (let key of map.keys()) { console.log(key); } // "F" // "T" for (let value of map.values()) { console.log(value); } // "no" // "yes" for (let item of map.entries()) { console.log(item[0], item[1]); } // "F" "no" // "T" "yes" // 或者 for (let [key, value] of map.entries()) { console.log(key, value); } // 等同於使用map.entries() for (let [key, value] of map) { console.log(key, value); }
Map轉換爲數組
使用擴展運算符(...)
let mao = new Map().set(true, 7).set({foo: 3}, ['abc']); [...mao]; //[ [true, 7], [{foo: 3}, ['abc']] ]
轉換爲數組結構以後,結合數組的map()
方法,filter()
方法能夠實現Map的遍歷和過濾。Map自己沒有map和filter方法,可是有一個forEach方法
let map0 = new Map() .set(1, 'a') .set(2, 'b') .set(3, 'c'); let map1 = new Map( [...map0].filter(([k, v]) => k < 3) ); // 產生Map結構 {1 => 'a', 2 => 'b'} let map2 = new Map( [...map0].map(([k, v]) => [k * 2, '_' + v]) ); // 產生Map結構 {2 => '_a', 4 => '_b', 6 => '_c'}
數組轉爲Map
new Map([[true, 7], [{foo: 3}, ['abc']]]) // Map {true => 7, Object {foo: 3} => ['abc']}
下面的例子中,字符串true和布爾值true是兩個不一樣的鍵。
var m = new Map([ [true, 'foo'], ['true', 'bar'] ]); m.get(true) // 'foo' m.get('true') // 'bar'
若是對同一個鍵屢次賦值,後面的值將覆蓋前面的值。
let map = new Map(); map .set(1, 'aaa') .set(1, 'bbb'); map.get(1) // "bbb"
上面代碼對鍵1連續賦值兩次,後一次的值覆蓋前一次的值。
若是讀取一個未知的鍵,則返回undefined。
new Map().get('asfddfsasadf') // undefined
注意,只有對同一個對象的引用,Map結構纔將其視爲同一個鍵。這一點要很是當心。
var map = new Map(); map.set(['a'], 555); map.get(['a']) // undefined
上面代碼的set和get方法,表面是針對同一個鍵,但實際上這是兩個值,內存地址是不同的,所以get方法沒法讀取該鍵,返回undefined。
由上可知,Map的鍵其實是跟內存地址綁定的,只要內存地址不同,就視爲兩個鍵。這就解決了同名屬性碰撞(clash)的問題,咱們擴展別人的庫的時候,若是使用對象做爲鍵名,就不用擔憂本身的屬性與原做者的屬性同名。
若是Map的鍵是一個簡單類型的值(數字、字符串、布爾值),則只要兩個值嚴格相等,Map將其視爲一個鍵,包括0和-0。另外,雖然NaN不嚴格相等於自身,但Map將其視爲同一個鍵。
let map = new Map(); map.set(NaN, 123); map.get(NaN) // 123 這裏是同一個鍵 map.set(-0, 123); map.get(+0) // 123