基礎教程 6. 數據去重算法、字符串經常使用方法

這是我參與8月更文挑戰的第5天,活動詳情查看:8月更文挑戰javascript

1、數組去重算法

1.1 雙 for 循環去重

思路:html

  1. 依次拿出數組中的每一項(排除最後一項:最後一項後面沒有須要比較的內容)
  2. 和當前取出向後面的每一項依次比較
  3. 若是發現有重複的,咱們把找到的這個重複項在原有數組中刪除(ary.splice)
var ary = [1, 3, 3, 3, 5, 4];

for (var i = 0; i < ary.length - 1; i++) {
  var item = ary[i];
  // item: 依次拿出數組的每一項
  // i 當前拿出來的數組項的索引值
  // => 用當前項和後面的項比較,因此後面的第一項的索引是 i + 1
  for (var k = i + 1; k < ary.length; k++) {
    if (item === ary[k]) {
      // => 若是咱們從容數組中取出來的項和後面的相等說明後面有重複項,因此須要刪除當前項
      // ary.splice(k, 1);
      /* * 可是直接這樣刪除後一個問題,就是數組塌陷;當咱們把當前項刪除後,後面的每一項都要向前移動一個,也就是 原有數組的索引起生了改變,此時咱們的k繼續累加1,下一次再拿出來的結果就會跳過一位 * 原數組 [1, 3, 3, 3, 5, 4] * 索引: 0 1 2 3 4 5 * 循環 * k = 2 後面有重複的3,刪除索引爲2的位置上的3,刪除以後 數組變成: * [1, 3, 3, 5, 4]; * 索引:0 1 2 3 4 * 此時,在不刪的狀況下,原數組中第二個3的索引是2,可是刪除後,原來索引爲2的那個3的索引變成了1,當i再++時,i就變成了3,因此就會漏掉一項。 * * * */
      ary.splice(k, 1);
      k--; // 刪除之後不能讓k累加了,因此先給k--,而後再++至關於沒加沒減
    }
  }
}
console.log(ary);
複製代碼

1.2 對象法去重

原理:基於對象的屬性名不能重複,咱們能夠實現高性能的數組去重java

步驟:算法

  1. 建立一個空對象
  2. 遍歷數組中的每一項,把數組每一項存儲的值,當作對象的屬性名和屬性值存儲起來。形如 {數組項1:數組項1, 數組項2: 數組項2}

第一次遍歷時:數組項 1, 對象:{1: 1} 第二次遍歷時:數組項 3, 對象:{1: 1, 3: 3} 3. 在存儲起來作一個判斷,判斷當前對象中是否存在這個屬性了,若是不存在 對象[屬性名] 就是undefined,說明這一個數組項在以前沒有出現過,沒出現就說明沒有重複,而後直接存儲在對象裏。若是在以前出現過了,此時 對象[屬性名] 的值就不是undefined,此時就不要存儲到對象中,同時刪除這一項。數組

var obj = {};

for (var i = 0; i < ary.length; i++) {
  var item = ary[i];
  if (obj[item] !== undefined) {
    // ary.splice(i, 1); 這種刪除方式很差,若是數組很長,咱們刪除中間的某一項,後面的全部的索引都會從新計算,很是消耗性能。因此咱們採用下面這種刪除方式:
    // 1. 用數組的最後一項替換當前項
    // 2. 把數組的最後一項刪除
    // 例如:數組var ary = [12, 23, 23, 34, 56] 想刪除第二個23
    // 先把第二個23獲取到 ary[2]
    // 再把數組的最後一項獲取到:ary[ary.length - 1]
    // 而後再把23換成數組最後一項,ary[2] = ary[ary.length - 1]
    // 最後刪除最後一項: ary.length--;

    ary[i] = ary[ary.length - 1]; // ary[i] 就是當前項,而且和再此以前已經重複過了
    ary.length--;
  } else {
    // 不然的狀況就是:數組當前項在以前沒有重複過,此時須要存儲到對象裏面
    obj[item] = item
  }
}

複製代碼

2、字符串經常使用方法

字符串特色:

字符串:字符串是被單引號或雙引號包裹的零到多個字符。是js中基本數據類型。 在字符串中的每一個字符,瀏覽器也都給他們分配了一個索引,第一字符的索引是0,第二字符的索引是1,第三個字符的索引是2...,因此經過 字符串[索引]的方式能夠獲取對應索引位置的字符。 字符串也是有length屬性的,表明字符串中字符的個數;瀏覽器

tips: 有長度、有索引是否是能夠用經過for 循環遍歷它?markdown

var str = '江外琉璃EverestTraining';
複製代碼

字符串經常使用方法

1. 經過制定索引獲取字符或ASCII

  • 1.1 charAt(index) 獲取字符串中索引爲index的字符。
var s = str.charAt(3);
console.log(s);
複製代碼
  • 1.2 charCodeAt(index) 獲取字符串中指定索引位置的字符的Unicode編碼值,返回的是一個 0 - 65535的整數
var code = str.charCodeAt(5); // 69
複製代碼

2 複製和截取字符串

  • 2.1 substr(n, m); 從n開始截取m個,若不寫m,則截取到末尾。若是n和m都不寫,這截取所有;
var s1 = str.substr(1, 2);
var s2 = str.substr(1);
var s3 = str.substr();
console.log(s1, s2, s3);
複製代碼
  • 2.2 substring(n, m); 從索引n開始截取,截取到索引爲m結束(不包含m),若是隻寫n,是從n開始截取到末尾;若是一個都不寫,那就是截取所有;
var s4 = str.substring(1, 3);
var s5 = str.substring(1);
var s6 = str.substr();
console.log(s4, s5, s6);

複製代碼

3. 轉換大小寫(只能轉英文字母)

  • 3.1 大寫轉成小寫 toLowerCase()
var s7 = 'A'.toLocaleLowerCase();
console.log(s7);
複製代碼
  • 3.2 小寫轉大寫 toUpperCase()
var s8 = 'a'.toUpperCase();
console.log(s8);
複製代碼

4. 獲取指定字符在字符串中出現的位置

  • 4.1 indexOf() 獲取字符在字符串中首次出現的位置,若是字符串中不包含這個字符,則返回-1
var idx1 = str.indexOf('珠');
console.log(idx1);

複製代碼
  • 4.2 lastIndexOf() 獲取字符在字符串中最後一次出現的位置,若是字符串中不包含這個字符,則返回-1
var idx2 = str.indexOf('E');
console.log(idx2);
複製代碼

5. split() 按照指定的分隔符把字符串拆分紅數組

數組中的 join 方法這個相反,join 是根據指定的分隔符數組項拼接成字符串dom

var str2 = 'I am a Front-end Engineer';
var ary = str2.split(' '); // 根據空格把 str2 拆分紅一個數組
console.log(ary);
複製代碼

6. replace() 字符串替換

var str3 = 'liuliudashun';
// 5.1 replace(old, new)
var s9 = str3.replace('liuliu', '江外');
console.log(s9);

// 5.2 replace(old, function () { return new})
var s10 = str3.replace('liuliu', function () {
  return '江外'
});
console.log(s10);

複製代碼

7. match() 匹配,

若是匹配到,就返回一個數組,若是匹配不到就返回 nullpost

var str4 = 'abcdefabcggg';
var ary2 = str4.match('abc');
console.log(ary2);

複製代碼

3、Math對象

Math對象,是瀏覽器中內置的專門處理數學計算的對象,Math內置了不少的數學方法。性能

1. Math.abs(); 獲取絕對值

var m1 = Math.abs(-12.5);
var m2 = Math.abs(12.5);
console.log(m1, m2);

複製代碼

2. Math.floor(); 向下取整

var m3 = Math.abs(12.5);
console.log(m3);

複製代碼

3. Math.ceil(); 向上取整

var m4 = Math.ceil(12.5);
console.log(m4);

複製代碼

4. Math.round() 四捨五入

var m5 = Math.round(2.3);
var m6 = Math.round(3.7);
// 注意:負數是四捨六入
var m7 = Math.round(-2.4);
var m8 = Math.round(-2.6);
console.log(m5, m6, m7, m8);

複製代碼

5. Math.random() 生成一個0-1之間的隨機小數

var m9 = Math.random();
console.log(m9);
複製代碼

5.2 生成一個n-m之間的隨機數,不包含m。[n,m) 【左開右閉區間】的隨機數

var n, m;
var ran = Math.round(Math.random() * (m - n) + n);
複製代碼

思考:如何獲取一個字符串裏隨機的一個字符?

6. Math.sqrt(n) 獲取的n的算術平方根

var m10 = Math.sqrt(9);
console.log(m10); // 3

複製代碼

7. Math.PI 獲取圓周率

var pi = Math.PI();
console.log(pi);
console.log(pi.toFixed(2)); //給Math.PI() 保留2位小數; toFixed(x)是number的方法,做用:保留x位小數

複製代碼

4、隨即驗證碼

基礎版

  • 需求:
  1. 生成一個4位的隨機驗證碼
  2. 把驗證碼插入到頁面中展現出來

原理: 分析需求:

  1. 咱們學習過的可以隨機的只有隨機數,咱們須要經過數字和字符鏈接起來。
  2. 而字符串和數字有關聯的就是索引和length,而字符和索引數字是一一對應的,咱們要是生成一個隨機數字,而後經過字符串索引取得這個隨機數對應的字符,就能夠達到隨機字符的目的,既然是
  3. 咱們須要4個,就是說上面的事情須要幹4回,顯然須要一個for循環
  • 具體步驟:
  1. 準備隨機範圍A-Z a-z 0-9
  2. 設置一空字符串,後面獲得的字符都拼接到這個空字符串上
  3. 設置for循環,循環四次
  4. 獲取頁面中的div元素對象
  5. 經過設置div的innerHTML屬性,把驗證碼插入到頁面中

HTML代碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>江外-隨機驗證碼</title>
</head>
<body>
<div id="codeBox"></div>

<script src="js/7-隨機驗證碼while循環版.js"></script>
</body>
</html>
複製代碼
var strbase = 'ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789';

var code = '';
for (var i = 0; i < 4; i++) {
  // 1.
  var ran = Math.round(Math.random() * (strbase.length - 0) + 0);
  var char = strbase[ran];
  code += char;
}
var codeBox = document.getElementById('codeBox');
codeBox.innerHTML = code;

複製代碼

不重複驗證碼

  • 需求:不重複驗證碼,A和a算重複

  • 分析:

  1. 咱們之因此會重複,是由於隨機出字符串後拼接以前沒有檢查在已有的驗證碼中是否已經存在相同字符;因此咱們須要在拼接以前須要檢查當前字符在已有的驗證碼字符串中是否放出現過(indexOf)
  2. 如何解決大小寫也算重複呢?這樣解決,咱們把已經有的驗證碼所有轉成大寫,而後把咱們本次得到字符也轉成大寫(toUpperCase)而後再判斷是否出現過。若是沒有出現過再拼接,若是出現過就不拼接。
  3. 若是出現過了,對於for循環來講已經跑了一輪了,此時不能給i ++,由於咱們本輪沒有得到有效的字符。若是++了就會致使若是出現重複了,有一次的字符沒有拼接,最後循環四次只有三個字符。
  4. 爲了解決3中中說的問題,咱們不是直接在for循環中i++了,咱們在知足拼接條件,成功拼接後i++
function validateCode() {
  var strbase = 'ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789';
  var code = '';
  for (var i = 0; i < 4;) {
    // 1.
    var ran = Math.round(Math.random() * (strbase.length - 0) + 0);
    var char = strbase[ran];
    var upperChar = char.toUpperCase();
    var upperCode = code.toUpperCase();
    if (upperCode.indexOf(upperChar) === -1) {
      code += char;
      i++;
    }
  }
  return code;
}

var ranCode = validateCode();
var codeBox = document.getElementById('codeBox');
codeBox.innerHTML = ranCode;

複製代碼

不重複驗證碼 while 循環版

while循環

js中還有一種循環,就是while循環, while單詞的意思是當...的時候一直作某件事情,一直到條件不成立。

因此while循環表示只要條件成立就會執行循環體裏面的代碼。

while (循環的條件) {
    循環體
 }
複製代碼

思考:while循環的條件時什麼?只要不知足什麼條件咱們就該一直循環? ? 咱們循環幹什麼?獲取驗證碼 ? 驗證碼有什麼要求?4位不重複的 ? 咱們在循環中判斷重複與否,若是不重複,就拼接給code字符串,這個時候至關於獲取到一個有效的字符串。若是咱們得到字符串在以前已經存在過,這至關於咱們沒有獲取到有效字符,因此就須要繼續再來一次。重複執行這個操做,直到何時就再也不找了?是已經獲取到了4位驗證碼了。因此此時就該中止循環了

因此中止的條件是 code.length < 4 即只要code的字符串個數小於4就該接着隨機

function validateCode() {
  var strbase = 'ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789';
  var code = '';
  while (code.length < 4) {
    var ran = Math.round(Math.random() * (strbase.length - 0) + 0);
    var char = strbase[ran];
    var upperChar = char.toUpperCase();
    var upperCode = code.toUpperCase();
    if (upperCode.indexOf(upperChar) === -1) {
      code += char;
    }
  }
  return code;
}
var codeBox = document.getElementById('codeBox');
codeBox.innerHTML = validateCode();
複製代碼
相關文章
相關標籤/搜索