<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      JavaScript數組常見用法

      最近做一個項目中做一個競猜游戲界面,游戲規則和彩票是一樣的。在實現“機選一注”,“機選五注”的時候遇到數組的一些操作,例如產生['01', '02' ... '35']這樣的數組,隨機抽取不重復的元素重新組成數組等問題。回想這類問題在平時項目中遇到的機會非常多,何不歸納一下JavaScript數組的一些知識點,以供平時工作參考。

      JavaScript提供的數組非常靈活,相關的api也很豐富,例如fill,map,filter,sort等等,極大地方便了程序編寫。這里不介紹這些基本的api,而是通過工作中常用的使用場景來展示數組的強大。

      1.歸納計算

      在一個分頁表格中比如訂單表,要求根據訂單金額展示這一頁的訂單總金額。很多時候后端開發偷懶,把這種計算推給前端,可以使用reduce輕松實現個功能,代碼如下。

      var orders = [
          {
              userName: 'Anna',
              books: 'Bible',
              money: 21.2
          },
          {
              userName: 'Bob',
              books: 'War and peace',
              money: 26.5
          },
          {
              userName: 'Alice',
              books: 'The Lord of the Rings',
              money: 18.4
          }
      ];
      let total = orders.reduce((acc, curr) => {return acc + curr.money}, 0);
      console.log(total);

      在vue組件中,可以直接使用reduce表達式計算表格某一列的歸納總和,很方便,示例代碼如下:

      <tbody>
              <tr class="header-tr">
                <th>品名</th>
                <th>批號</th>
                <th>規格</th>
                <th>等級</th>
                <th>生產入庫(KG)</th>
                <th>退貨入庫(KG)</th>
                <th>返修入庫(KG)</th>
                <th>返修投料(KG)</th>
                <th>出庫(KG)</th>
                <th>庫存結存(件)</th>
                <th>庫存結存重量(KG)</th>
                <th>期初結存(件)</th>
                <th>期初結存重量(KG)</th>
              </tr>
              <template v-for="(item, key) in tableData">
                <template v-for="obj in item">
                  <tr>
                    <td>{{key}}</td>
                    <td>{{obj.batchNo}}</td>
                    <td>{{obj.spec}}</td>
                    <td>{{obj.level}}</td>
                    <td>{{obj.productionInbound}}</td>
                    <td>{{obj.refundInbound}}</td>
                    <td>{{obj.reworkInbound}}</td>
                    <td>{{obj.reworkFeeding}}</td>
                    <td>{{obj.outbound}}</td>
                    <td>{{obj.monthlyBalanceCount}}</td>
                    <td>{{obj.monthlyBalanceWeight}}</td>
                    <td>{{obj.preMonthlyBalanceCount}}</td>
                    <td>{{obj.preMonthlyBalanceWeight}}</td>
                  </tr>
                </template>
                <tr>
                  <th colspan="3">{{key}}小計</th>
                  <th>&nbsp;</th>
                  <th>{{ item.reduce((acc, curr) => acc + curr.productionInbound, 0) }}</th>
                  <th>{{ item.reduce((acc, curr) => acc + curr.refundInbound, 0) }}</th>
                  <th>{{ item.reduce((acc, curr) => acc + curr.reworkInbound, 0) }}</th>
                  <th>{{ item.reduce((acc, curr) => acc + curr.reworkFeeding, 0) }}</th>
                  <th>{{ item.reduce((acc, curr) => acc + curr.outbound, 0) }}</th>
                  <th>{{ item.reduce((acc, curr) => acc + curr.monthlyBalanceCount, 0) }}</th>
                  <th>{{ item.reduce((acc, curr) => acc + curr.monthlyBalanceWeight, 0) }}</th>
                  <th>{{ item.reduce((acc, curr) => acc + curr.preMonthlyBalanceCount, 0) }}</th>
                  <th>{{ item.reduce((acc, curr) => acc + curr.preMonthlyBalanceWeight, 0) }}</th>
                </tr>
              </template>

      2.快速生成數組

      工作中前端進度一般是先于后端的,前端畫頁面的時候后端服務一般還沒有寫好,這時前端要自己生成一些數據把頁面先做起來。有人可能會說用mock,但是小項目引用mock就太麻煩了。這時就要自己先生成一些數據,最常見的就是生成一個對象列表。下面就來討論生成數據的方式。

      2.1 Array(length)&Array.fill()&Array.map()

      構造函數Array()有兩個重載:

      new Array(element0, element1[, ...[, elementN]]):根據給定元素生成一個javascript數組,這些元素是逗號分割的。
      new Array(arrayLength):arrayLength是一個范圍在0到232-1之間的整數,這時方法返回一個長度為arrayLength的數組對象,注意數組此時沒有包含任何實際的元素,不是undefined,也不是null,使用console.log()打印出來是empty。如果傳入的arrayLength不滿足上面條件,拋出RangeError錯誤。

      使用Array(arrayLength)獲取到空數組之后,使用Array.fill()方法給數組填充初始值,再使用Array.map()方法給數組元素生成有意義的值。

      console.time("arr1");
      let arr1 = Array(10).fill(0).map((value, index) => {
          return ++index;
      });
      console.timeEnd("arr1");
      console.log(arr1);

      輸出結果如下:

       

       2.2 Array()&Array.from()

      Array.from:方法從一個類似數組或可迭代對象創建一個新的,淺拷貝的數組實例。代碼如下:

      console.time("arr2");
      let arr2 = Array.from(new Array(10), (value, index) => {
          return ++index;
      });
      console.timeEnd("arr2");
      console.log(arr2);

       

      執行結果如下:

       

      2.3 使用遞歸

      使用了遞歸和立即執行函數來生成數組。

      console.time("arr3")
      let arr3 = (function wallace(i) {
          return (i < 1) ? [] : wallace(i - 1).concat(i);
      })(10);
      console.timeEnd("arr3");

      執行結果如下:

      2.4 使用尾遞歸

      相對遞歸來說,尾遞歸效率更高。

      console.time("arr4")
      let arr4 = (function mistake(i, acc) {
          return (i < 10) ? mistake(i + 1, acc.concat(i)) : acc;
      })(1, []);
      console.timeEnd("arr4")
      console.log(arr4);

      執行結果如下:

      2.5 使用ES6中的Generator

      console.time("arr5");
      function* mistake(i) {
          yield i;
          if (i < 10) {
              yield* mistake(i + 1);
          }
      }
      let arr5 = Array.from(mistake(1));
      console.timeEnd("arr5");
      console.log(arr5);

      執行結果如下:

       

      2.6 使用apply和類數組對象

      console.time("arr6");
      let arr6 = Array.apply(null, {length: 10}).map((value, index) => index + 1);
      console.timeEnd("arr6");
      console.log(arr6);

      結果如下:

       

      3.數組去重

      3.1 對象屬性

      使用對象屬性不重名的特性。

      var arr = ['qiang','ming','tao','li','liang','you','qiang','tao'];
      console.time("nonredundant1");
      var nonredundant1 = Object.getOwnPropertyNames(arr.reduce(function(seed, item, index) {
          seed[item] = index;
          return seed;
      },{}));
      console.timeEnd("nonredundant1");
      console.log(nonredundant1);

      結果如下:

       

      3.2 使用Set

      set是一種類似數組的結構,但是set成員中沒有重復的值。set()函數可以接受一個數組或者類數組的參數,生成一個set對象。而Array.from方法用于將兩類對象轉為真正的數組:類似數組的對象(array-like object和可遍歷iterable)的對象包括 ES6 新增的數據結構 Set 和 Map)。

      var arr = ['qiang','ming','tao','li','liang','you','qiang','tao'];
      function unique (arr) {
          return Array.from(new Set(arr))
      }
      console.time("nonredundant2");
      var nonredundant2 = unique(arr);
      console.timeEnd("nonredundant2");
      console.log(nonredundant2);

      結果如下:

      3.3 使用for循環和splice

      function unique(arr) {
          for (var i = 0; i < arr.length; i++) {
              for (var j = i + 1; j < arr.length; j++) {
                  if (arr[i] == arr[j]) {         //第一個等同于第二個,splice方法刪除第二個
                      arr.splice(j, 1);
                      j--;
                  }
              }
          }
          return arr;
      }
      console.time("nonredundant3");
      var arr = ['qiang', 'ming', 'tao', 'li', 'liang', 'you', 'qiang', 'tao'];
      var nonredundant3 = unique(arr);
      console.timeEnd("nonredundant3");
      console.log(nonredundant3);

      結果如下:

      3.4 使用indexOf判斷去重

      function unique(arr) {
          var array = [];
          for (var i = 0; i < arr.length; i++) {
              if (array .indexOf(arr[i]) === -1) {
                  array .push(arr[i])
              }
          }
          return array;
      }
      var arr = ['qiang', 'ming', 'tao', 'li', 'liang', 'you', 'qiang', 'tao'];
      console.time("nonredundant4");
      var nonredundant4 = unique(arr);
      console.timeEnd("nonredundant4");
      console.log(nonredundant4);

      結果如下:

      3.5 使用sort排序去重

      function unique(arr) {
          arr = arr.sort()
          var arrry = [arr[0]];
          for (var i = 1; i < arr.length; i++) {
              if (arr[i] !== arr[i - 1]) {
                  arrry.push(arr[i]);
              }
          }
          return arrry;
      }
      
      var arr = ['qiang', 'ming', 'tao', 'li', 'liang', 'you', 'qiang', 'tao'];
      console.time("nonredundant5");
      var nonredundant5 = unique(arr);
      console.timeEnd("nonredundant5");
      console.log(nonredundant5);

      結果如下:

       

      3.6 使用filter

      function unique(arr) {
          var obj = {};
          return arr.filter(function(item, index, arr){
              return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
          })
      }
      var arr = ['qiang', 'ming', 'tao', 'li', 'liang', 'you', 'qiang', 'tao'];
      console.time("nonredundant6");
      var nonredundant6 = unique(arr);
      console.timeEnd("nonredundant6");
      console.log(nonredundant6);

      結果如下:

      3.7 使用Map數據結構去重

      function unique(arr) {
          let map = new Map();
          let array = new Array();  // 數組用于返回結果
          for (let i = 0; i < arr.length; i++) {
              if (map.has(arr[i])) {  // 如果有該key值
                  map.set(arr[i], true);
              } else {
                  map.set(arr[i], false);   // 如果沒有該key值
                  array.push(arr[i]);
              }
          }
          return array;
      }
      
      var arr = ['qiang', 'ming', 'tao', 'li', 'liang', 'you', 'qiang', 'tao'];
      console.time("nonredundant7");
      var nonredundant7 = unique(arr);
      console.timeEnd("nonredundant7");
      console.log(nonredundant7);

      結果如下:

      3.8 使用reduce和include去重

      function unique(arr){
          return arr.reduce((prev,cur) => prev.includes(cur) ? prev : [...prev,cur],[]);
      }
      var arr = ['qiang', 'ming', 'tao', 'li', 'liang', 'you', 'qiang', 'tao'];
      console.time("nonredundant8");
      var nonredundant8 = unique(arr);
      console.timeEnd("nonredundant8");
      console.log(nonredundant8);

      結果如下:

      4. 數組隨機選取

      這個需求在實際開發中也很常見,比如彩票隨機一注,隨機五注,機動車號牌隨機選一個等等。

      4.1 大于等于0小于1的隨機數

      function getRandom() {
        return Math.random();
      }

       

      4.2 兩數之間的隨機數

      返回一個在指定值之間的隨機數,這個隨機數大于等于min,小于max。

      function getRandomArbitrary(min, max) {
        return Math.random() * (max - min) + min;
      }

       

      4.3 兩數之間的隨機整數

      返回一個在指定值之間的隨機整數,這個值大于等于min(如果min不是整數,則大于等于min的向上取整數),且小于max(不等于)。

      function getRandomInt(min, max) {
        min = Math.ceil(min);
        max = Math.floor(max);
        return Math.floor(Math.random() * (max - min)) + min; //不含最大值,含最小值
      }

       

      4.4 兩數之間的隨機整數,包含兩數

      上面的getRandomInt()方法返回的隨機數包含了最小值,但不包含最大值,下面的方法同時包含最小值和最大值。

      function getRandomIntInclusive(min, max) {
        min = Math.ceil(min);
        max = Math.floor(max);
        return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值 
      }

      4.5 Math.random()的隨機問題

      這種方式是使用Array.sort()和Math.random()結合的方法,Math.random()返回的是一個0-1之間(不包括1)的偽隨機數,注意這不是真正的隨機數。

      var letter = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
      function shuffle1(arr) {
          return arr.sort(() => 0.5 - Math.random())
      }
      console.time("shuffle1");
      letter = shuffle1(letter);
      console.timeEnd("shuffle1");
      console.log(letter);

      這種方式并不是真正的隨機,來看下面的例子。對這個10個字母數組排序1000次,假設這個排序是隨機的話,字母a在排序后的數組中每個位置出現的位置應該是1000/10=100,或者說接近100次。看下面的測試代碼:

      let n = 1000;
      let count = (new Array(10)).fill(0);
      for (let i = 0; i < n; i++) {
          let letter = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
          letter.sort(() => Math.random() - 0.5);
          count[letter.indexOf('a')]++
      }
      console.log(count); 

      結果如下:

      可以看出元素a的位置在0到9出現的次數并不是接近100的。

      原因有兩點:

      1. Math.random()方法產生的偽隨機數并不是在0到1之間均勻分布,不能提供像密碼一樣安全的隨機數字。
      2. Array.prototype.sort(compareFunction)方法中的compareFunction(a, b)回調必須總是對相同的輸入返回相同的比較結果,否則排序的結果將是不確定的。

      這里sort(() => 0.5 - Math.random())沒有輸入,跟談不上返回相同的結果,所以這個方法返回的結果不是真正的數組中的隨機元素。 

      4.6 隨機值排序

      既然(a, b) => Math.random() - 0.5 的問題是不能保證針對同一組 a、b 每次返回的值相同,那么我們不妨將數組元素改造一下,比如將元素'a'改造為{ value: 'a', range: Math.random() },數組變成[{ value: 'a', range: 0.10497314648454847 }, { value: 'b', range: 0.6497386423992171 }, ...],比較的時候用這個range值進行比較,這樣就滿足了Array.sort()的比較條件。代碼如下:

      let letter = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
      function shuffle2(arr) {
          let new_arr = arr.map(i => ({value: i, range: Math.random()}));
          new_arr.sort((a, b) => a.r - b.r);
          arr.splice(0, arr.length, ...new_arr.map(i => i.value));
      }
      console.time("shuffle2");
      letter = shuffle2(letter);
      console.timeEnd("shuffle2");
      console.log(shuffle2); 

      輸出結果如下:

       我們再使用上面的方式測試一下,看看元素a元素是不是隨機分布的。

      let n = 1000, count = (new Array(10)).fill(0);
      for (let i = 0; i < n; i++) {
          let letter = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
          letter = shuffle2(letter)
          count[letter.indexOf('a')]++
      }
      console.log(count); 

      結果如下:

      從這里可以看出,元素a在位置0到9出現的次數是接近100的,也就是說元素a是隨機分布的,其他的元素也是,這時再從這個新數組中截取前幾個元素就是想要的數組了。

      4.7 洗牌算法

      上面的sort算法,雖然滿足了隨機性的需求,但是性能上并不是很好,很明顯為了達到隨機目的把簡單數組變成了對象數組,最后又從排序后的數組中獲取這個隨機數組,明顯走了一些彎路。

      洗牌算法可以解決隨機性問題,洗牌算法的步驟如下:

      1. 數組arr,有n個元素,存放從1到n的數值;
      2. 生成一個從0到n-1的隨機數x;
      3. 輸出arr下標為x的元素,即第一個隨機數;
      4. 將arr的尾元素和下標為x的元素值互換;
      5. 同步驟2,生成一個從0到n-2的隨機數x;
      6. 輸出arr下標為x的數組,第二個隨機數;
      7. 將arr倒數第二個元素和下標為x的元素互換;
      8. 重復執行直至輸出m個數為止;

      洗牌算法是真的隨機的嗎,換言之洗牌算法真的可以隨機得到n個元素中m個嗎?下面拿一個只有5個元素的數組來說明。

       數組有5個元素,如下圖。

       

      從5個元素隨機抽出一個元素和最后一個換位,假設抽到3,概率是1/5,如下圖。注意其他任意4個元素未被抽到的概率是4/5。最終3出現在最后一位的概率是1/5。

       

      將抽到的3和最后一位的5互換位置,最后一位3就確定了,如下圖:

       

      再從前面不確定的4個元素隨機抽一個,這里注意要先考慮這4個元素在第一次未被抽到的概率是4/5,再考慮本次抽到的概率是1/4,然后乘一下得到1/5。注意其他任意3個未被抽到的概率是3/4。5出現在倒數第二位的概率是4/5*1/4=1/5如下圖:

      現在最后2個元素確定了,從剩下的3個元素中任意抽取一個,概率是1/3,身下任意2個未被抽到的概率是2/3,但是要考慮上一次未被抽到的概率是3/4,以及上上一次未被抽到的概率是4/5,于是最終1出現在倒數第三位的概率是1/3*3/4*4/5=1/5。

       

      現在倒數3個元素已經確定,剩下的2個元素中任意取一個,概率是1/2,但是要考慮上一次未被抽到的概率是2/3,上上一次未被抽到的概率是3/4,上上上一次未被抽到的概率是4/5,最終4出現在倒數第4位的概率是1/2*2/3*3/4*4/5=1/5。

       

      最后還剩下一個2,它出現在倒數第5位的概率肯定也是1/5。不嫌啰嗦的話可以繼續看下去。

      現在倒數4個元素已經確定,剩下1個元素中任意取一個,概率是1,但要考慮上一次未被抽中的概率是1/2,上上一次未被抽中的概率是2/3,上上上一次未被抽中的概率是3/4,上上上上一次未被抽中的概率是4/5,于是2出現在倒數5位置的概率是1*1/2*2/3*3/4*4/5=1/5。

      有了算法,下面給出洗牌算法的代碼:

      let letter = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
      function shuffle3(arr) {
          let i = arr.length, t, j;
          while (i) {
              j = Math.floor(Math.random() * (i--)); //
              t = arr[i];
              arr[i] = arr[j];
              arr[j] = t;
          }
      }
      console.time("shuffle3");
      shuffle3(letter);
      console.timeEnd("shuffle3");
      console.log(letter) 

      運行結果如下:

       

       還有最后一個問題,我們來驗證一下,還是和上面的方法一樣,隨機排序1000次,看看字母a出現在0-9個位置的概率是多少,理論上應該是1000/10=100。來看下面的代碼:

      let n = 1000;
      let count = (new Array(10)).fill(0);
      function shuffle3(arr) {
          let i = arr.length, t, j;
          while (i) {
              j = Math.floor(Math.random() * (i--)); //
              t = arr[i];
              arr[i] = arr[j];
              arr[j] = t;
          }
      }
      for (let i = 0; i < n; i++) {
          let letter = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
          shuffle3(letter);
          count[letter.indexOf('a')]++
      }
      console.log(count); 

      結果如下:

       

      可以看到基本上都是接近100的,可以說明洗牌算法是隨機的。

      4.8 機選彩票

      最近開發做了一個模擬彩票游戲的功能,彩票有機選,其實就是隨機選取,下面以雙色球為例來看看實現的效果是什么樣的。雙色球前區從1到33個小球,后區從1到16個小球,一注彩票中前區至少選6個,后區至少選1個。這里使用洗牌算法實現,如下圖:

      5.數組扁平化

      數組扁平化就是把一個多維數組轉換成一維的。

      5.1 flat方法

      es6已經實現了數組的flat方法,使用方法很簡單,如[1, [2, 3]].flat()。flat方法可以傳入一個參數表示最多處理多深的數組。

      var arr1 = [1, 2, [3, 4]];
      arr1 = arr1.flat();
      console.log(arr1); // [1, 2, 3, 4]
      
      var arr2 = [1, 2, [3, 4, [5, 6]]];
      arr2 = arr2.flat();
      console.log(arr2); //[1, 2, 3, 4, [5, 6]]
      
      var arr3 = [1, 2, [3, 4, [5, 6]]];
      arr3 = arr3.flat(2);
      console.log(arr3); // [1, 2, 3, 4, 5, 6]
      
      var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
      arr4 = arr4.flat(Infinity);
      console.log(arr4); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 

      5.2 reduce實現

      上面介紹數組歸納的時候講到過reduce,它對數組中的每個元素執行一個指定的函數,最終將結果匯總為單個返回值,然后配合concat方法合并兩個數組,來實現扁平化。

          let arr = [1, [2, 3, [4, 5]]];
          function flatten1(arr) {
              return arr.reduce((prev, curr) => prev.concat(Array.isArray(curr) ? flatten1(curr) : curr), []);
          }
          console.time("flatten1");
          console.log(flatten1(arr));
          console.timeEnd("flatten1"); 

      結果如下:

       

       5.3 toString & split

      調用數組的toString方法,不管數組有幾層,都可以將數組變為字符串并用逗號分隔,然后再使用split分隔,map還原為數組。

      let arr = [1, [2, 3, [4, 5]]];
      function flatten2(arr) {
          return arr.toString().split(",").map(i => Number(i));
      }
      console.time("flatten2");
      console.log(flatten2(arr));
      console.timeEnd("flatten2"); 

      結果如下:

       

       5.4 join & split

      調用對數組調用join方法,不管數組有幾層,都可以將數組變成字符串并用逗號分隔,然后使用split分隔,map還原為數組。

      let arr = [1, [2, 3, [4, 5]]];
      function flatten3(arr) {
          return arr.join().split(",").map(i => parseInt(i));
      }
      console.time("flatten3");
      console.log(flatten3(arr));
      console.timeEnd("flatten3"); 

      結果如下:

       

      5.5 遞歸

      這種方法和第一種類似,只不過是用map得到數組。

      function flatten4(arr) {
          let res = [];
          arr.map(item => {
              if(Array.isArray(item)) {
                  res = res.concat(flatten4(item));
              } else {
                  res.push(item);
              }
          });
          return res;
      }
      let arr = [1, [2, 3, [4, 5]]];
      console.time("flatten4");
      console.log(flatten4(arr));
      console.timeEnd("flatten4"); 

      結果如下:

       

      5.6 擴展運算符

      es6中的擴展運算符可以展開數組,將數組元素轉換成逗號分隔的對象。

      function flatten5(arr) {
          while (arr.some(item => Array.isArray(item))) {
              arr = [].concat(...arr);
          }
          return arr;
      }
      let arr = [1, [2, 3, [4, 5]]];
      console.time("flatten5");
      console.log(flatten5(arr));
      console.timeEnd("flatten5"); 

      結果如下:

        

      5.7 使用Generator函數

      Generator函數也可以遞歸調用,這種方式比較新穎。

      function* flatten6(array) {
          for (const item of array) {
              if (Array.isArray(item)) {
                  yield* flatten6(item);
              } else {
                  yield item;
              }
          }
      }
      let arr = [1, [2, 3, [4, 5]]];
      console.time("flatten6");
      console.log(flatten6(arr));
      console.timeEnd("flatten6"); 

      結果如下:

      6.總結

      數組是平時開發時最常用到的數據結構,充分了解數組的技巧以及相關的api對開發工作大有幫助,首先要做到的是了解這些知識點,然后重要的是在開發中能夠使用起來,這樣才能讓他們迸發出生命力。本文如有錯誤,請大家指正。

       

      posted @ 2020-05-24 15:17  nd  閱讀(987)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 色偷偷女人的天堂亚洲网| 无码午夜福利片| 亚洲V天堂V手机在线| 亚洲色欲久久久久综合网| 国产一区二区不卡精品视频| 久久精品国产蜜臀av| 久久久无码一区二区三区| 18禁亚洲一区二区三区| 亚洲av综合色一区二区| 精品国产高清中文字幕| 最新偷拍一区二区三区| 1区2区3区4区产品不卡码网站 | 亚洲成av人片无码不卡播放器| 99riav国产精品视频| 国产日韩一区二区三区在线观看 | 深夜视频国产在线观看| 国产精品综合在线免费看| 国产精品久久久久久福利| 精品日韩色国产在线观看| 99无码中文字幕视频| 亚洲AV高清一区二区三区尤物| 99久久亚洲综合网精品| 韩国精品久久久久久无码| 少妇被躁爽到高潮| 久久99久国产精品66| 久久亚洲av成人一二三区| 国产精品一区在线蜜臀| 欧美高清狂热视频60一70| 亚洲成女人图区一区二区| 国产成人精品手机在线观看| 亚洲精品一区二区动漫| 成人无码区在线观看| 国产精品av免费观看| 在线视频中文字幕二区| 亚洲av色夜色精品一区| 亚洲精品美女久久久久9999 | 日韩中文字幕精品人妻| 欧美日韩中文国产一区| 国产在线拍揄自揄拍无码| 国产91午夜福利精品| 国产伦精品一区二区三区免费迷|