step by step教你常用JS方法封装(四)-数组方法

本文参考原文-http://bjbsair.com/2020-03-25/tech-info/6344.html

手把手教你常用JS方法封装(四)-数组方法

持续更新中...

封装方法传送门:

使用方法非常简单,只需放到你的 utils.js 工具文件中,直接 export const 加上我的封装方法,在别的文件中使用{方法1,方法2,方法3...}引用后就可以直接使用了!

001.冒泡排序

升序 bubbleAsSort()

bubbleAsSort = arr => {  
  for (let i = 0; i < arr.length - 1; i++) {  
    for (let j = 0; j < arr.length - 1 - i; j++) {  
      if (arr[j] > arr[j + 1]) {  
        let temp = arr[j + 1];  
        arr[j + 1] = arr[j];  
        arr[j] = temp;  
      }  
    }  
  }  
  return arr;  
}  
复制代码

降序 bubbleDeSort()

bubbleDeSort = arr => {  
  for (let i = 0; i < arr.length - 1; i++) {  
    for (let j = 0; j < arr.length - 1 - i; j++) {  
      if (arr[j] < arr[j + 1]) {  
        let temp = arr[j + 1];  
        arr[j + 1] = arr[j];  
        arr[j] = temp;  
      }  
    }  
  }  
  return arr;  
}  
复制代码

002.选择排序

升序 selectAsSort()

selectAsSort = arr => {  
  let minIndex, temp;  
  for (let i = 0; i < arr.length - 1; i++) {  
    minIndex = i;  
    for (let j = i + 1; j < arr.length; j++) {  
      if (arr[j] < arr[minIndex]) {  
        minIndex = j;  
      }  
    }  
    temp = arr[i];  
    arr[i] = arr[minIndex];  
    arr[minIndex] = temp;  
  }  
  return arr;  
}  
复制代码

降序 selectDeSort()

selectDeSort = arr => {  
  let minIndex, temp;  
  for (let i = 0; i < arr.length - 1; i++) {  
    minIndex = i;  
    for (let j = i + 1; j < arr.length; j++) {  
      if (arr[j] > arr[minIndex]) {  
        minIndex = j;  
      }  
    }  
    temp = arr[i];  
    arr[i] = arr[minIndex];  
    arr[minIndex] = temp;  
  }  
  return arr;  
}  
复制代码

003.插入排序

升序 insertAsSort()

insertAsSort = arr => {  
  let current, preIndex;  
  for (let i = 1; i < arr.length; i++) {  
    current = arr[i];  
    preIndex = i - 1;  
    while (preIndex >= 0 && arr[preIndex] > current) {  
      arr[preIndex + 1] = arr[preIndex];  
      preIndex--;  
    }  
    arr[preIndex + 1] = current;  
  }  
  return arr;  
}  
复制代码

降序 insertDeSort()

insertDeSort = arr => {  
  let current, preIndex;  
  for (let i = 1; i < arr.length; i++) {  
    current = arr[i];  
    preIndex = i - 1;  
    while (preIndex >= 0 && arr[preIndex] < current) {  
      arr[preIndex + 1] = arr[preIndex];  
      preIndex--;  
    }  
    arr[preIndex + 1] = current;  
  }  
  return arr;  
}  
复制代码

004.数组去重

arrDemp1 = arr => {  
  let newArr = [];  
  let m = {};  
  for (let i = 0; i < arr.length; i++) {  
    let n = arr[i];  
    if (m[n]) {  
  
    } else {  
      newArr.push(arr[i]);  
      m[n] = true;  
    }  
  }  
  return newArr;  
}  
  
//遍历数组法  
arrDemp2 = arr => {  
    let temp = [];  
    for (let i = 0; i < arr.length; i++) {  
        //indexOf()方法可返回某个指定的字符串或数组值在字符串或数组中首次出现的位置,若不在其中则返回-1  
        if (temp.indexOf(arr[i]) === -1)  
            temp.push(arr[i]);  
    }  
    return temp;  
}  
  
//排序法  
arrDemp3 = arr => {  
    let temp = [];  
    arr.sort();  
    temp.push(arr[0]);  
    //因为数组已经经过排序,所以重复元素一定相邻,判断当前数组第i个元素与temp的最后一个元素是否相等,不相等时才复制元素  
    for (let i = 1; i < arr.length; i++) {  
        if (arr[i] != temp[temp.length - 1])  
            temp.push(arr[i]);  
    }  
    return temp;  
}  
  
//对象法  
arrDemp4 = arr => {  
    let temp = [];  
    let json = {};  
    //将当前数组的元素值当作对象的属性,遍历数组,比对对象,如果对象的这个属性不存在则将当前数组元素复制到临时数组,并添加该属性且将属性值赋值为1  
    for (let i = 0; i < arr.length; i++) {  
        if (!json[arr[i]]) {//如果对象没有该属性  
            temp.push(arr[i]);  
            json[arr[i]] = 1;//添加属性,将属性值赋值为1  
        }  
    }  
    return temp;  
}  
复制代码

也可以使用ES6中的new Set,一步到位

let arr = [1,2,3,5,4,5,4,3,6]  
let arrDemp = new Set(arr)  //arrDemp是一个对象  
let newArr = [...arrDemp]   //把arrDemp转化成数组  
console.log(newArr);  
复制代码

005.数组对象去重

将对象数组中属性相同的项去重

/*  
*   objArr 对象数组  
*   para 将要进行去重的字段(String类型)  
*/  
objArrDemp1 = (objArr, para) => {  
    let result = [];  
    let temp = {};  
    for (let i = 0; i < objArr.length; i++) {  
        let parameter = objArr[i][para];  
        if (temp[parameter]) {  
            continue;//不继续执行接下来的代码,跳转至循环开头  
        }  
        temp[parameter] = true;//为temp添加此属性(parameter)且将其值赋为true  
        result.push(objArr[i]);//将这一项复制到结果数组result中去  
    }  
    return result;  
}  
  
objArrDemp2 = (objArr, para) => {  
    let hash = {};  
    //reduce方法有两个参数,第一个参数是一个callback,用于针对数组项的操作;第二个参数则是传入的初始值,这个初始值用于单个数组项的操作。  
    objArr = objArr.reduce(function (item, next) {//这是针对数组项操作的函数,对于每个数组项,reduce方法都会将其调用一次  
        hash[next[para]] ? '' : hash[next[para]] = true && item.push(next);  
        return item;  
    }, []);//初始值是一个空对象,使用reduce方法返回的是空对象通过叠加执行之后的结果  
    return objArr;  
}  
  
  
//  测试数据:  
let objArr = [{ name: 'a', age: 1 }, { name: 'a', age: 2 }, { name: 'b', age: 2 }]  
console.log(objArrDemp1(objArr,'name'));    // [ { name: 'a', age: 1 }, { name: 'b', age: 2 } ]  
console.log(objArrDemp1(objArr,'age'));     // [ { name: 'a', age: 1 }, { name: 'a', age: 2 } ]  
复制代码

006.统计数组中各个元素出现的次数

staArrNum = arr => {  
  let obj = {};  
  for (let i = 0; i < arr.length; i++) {  
    let m = arr[i];  
    if (obj.hasOwnProperty(m)) {  
      obj[m] += 1;  
    } else {  
      obj[m] = 1;  
    }  
  }  
  return obj;  
}  
  
//  测试数据  
let arr = [1, 2, 3, 6, 5, 3, 2, 1, 2, 3, 2, 1]  
console.log(staArrNum(arr));  //    { '1': 3, '2': 4, '3': 3, '5': 1, '6': 1 }  
复制代码

007.在数组中找指定的元素,返回下标

arrFinNum = function (arr,num) {  
  let index = -1;  
  for (let i = 0; i < arr.length; i++) {  
    if (num == arr[i]) {  
      index = i;  
      break;  
    }  
  }  
  return index;  
}  
  
//  测试数据  
let arr = [1,2,3,4,5,6]  
console.log(arrFinNum(arr,4));  // 3  
复制代码

008.删除数组中的元素

delArrNum = (arr,val) => {  
  let index = arrFinNum(arr, val) //调用了前面自行添加的arrFinNum方法  
  if (index != -1) {  
    return arr.splice(index, 1);  
  }  
}  
复制代码

示例

arrFinNum = (arr, num) => {  
  let index = -1;  
  for (let i = 0; i < arr.length; i++) {  
    if (num == arr[i]) {  
      index = i;  
      break;  
    }  
  }  
  return index;  
}  
  
delArrNum = (arr,val) => {  
  let index = arrFinNum(arr, val) //调用了前面自行添加的arrFinNum方法  
  if (index != -1) {  
    return arr.splice(index, 1);  
  }  
}  
  
//  测试数据  
let arr = [1, 2, 3, 4, 5, 6]  
console.log(delArrNum(arr,2));  //  [ 2 ]  
复制代码

009.二分查找

//非递归实现  
binarySearch = (arr, key) => {  
  let high = arr.length - 1,  
    low = 0;  
  while (low <= high) {  
    let m = Math.floor((high + low) / 2);  
    if (arr[m] == key) {  
      return m;  
    }  
    if (key > arr[m]) {  
      low = m + 1;  
    } else {  
      high = m - 1;  
    }  
  }  
  return false;  
}  
  
//  测试数据  
let arr = [-1, 1, 3, 4, 5, 8, 32, 234, 12, 42];  
console.log(binarySearch(arr, 4));  
复制代码
//递归实现  
binarySearch = (arr, low, high, key) => {  
  if (low > high) {  
    return -1;  
  }  
  let mid = parseInt((high + low) / 2);  
  if (arr[mid] == key) {  
    return mid;  
  } else if (arr[mid] > key) {  
    high = mid - 1;  
    return binarySearch(arr, low, high, key);  
  } else if (arr[mid] < key) {  
    low = mid + 1;  
    return binarySearch(arr, low, high, key);  
  }  
};  
  
//  测试数据  
let arr = [-1, 1, 3, 4, 5, 8, 32, 234, 12, 42];  
console.log(binarySearch(arr, 0, 13, 5));  
复制代码

010.对象处理为数组对象

/**  
 *  obj 需要处理的对象  
 */  
objToArrObj = obj => {  
  let arr = []  
  for(let i in obj){  
    arr.push({[i]:obj[i]})  
  }  
  return arr  
}  
  
//  测试数据  
let obj = {20180410: 5, 20180411: 13, 20180412: 26, 20180413: 16}  
console.log(objToArrObj(obj));  
/*  
  [  
    { 20180410: 5 },  
    { 20180411: 13 },  
    { 20180412: 26 },  
    { 20180413: 16 }  
  ]  
*/  
复制代码

011.通过键查找对象数组中对应的下标、键、值

/**  
 *  arr 对象数组  
 *  index 要查找的键名  
 */  
objArrHandle = (arr,keyName) => {  
  let sub = arr.findIndex(item=>item[keyName])  
  let obj = arr[sub]  
  let key = Object.keys(obj)[0]  
  let value = obj[Object.keys(obj)]  
  return '下标:'+sub+' 键:'+key+' 值:'+value  
}  
  
//  测试数据  
let arr = [{ 20180410: 5 },{ 20180411: 13 },{ 20180412: 26 },{ 20180413: 16 }]  
console.log(objArrHandle(arr,20180412));  // 下标:2 键:20180412 值:26
```本文参考原文-http://bjbsair.com/2020-03-25/tech-info/6344/
  

![手把手教你常用JS方法封装(四)-数组方法](https://upload-images.jianshu.io/upload_images/21050011-14640c8b1e0b968c?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

  

持续更新中...
========

封装方法传送门:

**使用方法非常简单,只需放到你的 utils.js 工具文件中,直接 export const 加上我的封装方法,在别的文件中使用{方法1,方法2,方法3...}引用后就可以直接使用了!**

001.冒泡排序
========

**升序 bubbleAsSort()**

bubbleAsSort = arr => {
for (let i = 0; i < arr.length - 1; i++) {
for (let j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
let temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
复制代码


**降序 bubbleDeSort()**

bubbleDeSort = arr => {
for (let i = 0; i < arr.length - 1; i++) {
for (let j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] < arr[j + 1]) {
let temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
复制代码


002.选择排序
========

**升序 selectAsSort()**

selectAsSort = arr => {
let minIndex, temp;
for (let i = 0; i < arr.length - 1; i++) {
minIndex = i;
for (let j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
return arr;
}
复制代码


**降序 selectDeSort()**

selectDeSort = arr => {
let minIndex, temp;
for (let i = 0; i < arr.length - 1; i++) {
minIndex = i;
for (let j = i + 1; j < arr.length; j++) {
if (arr[j] > arr[minIndex]) {
minIndex = j;
}
}
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
return arr;
}
复制代码


003.插入排序
========

**升序 insertAsSort()**

insertAsSort = arr => {
let current, preIndex;
for (let i = 1; i < arr.length; i++) {
current = arr[i];
preIndex = i - 1;
while (preIndex >= 0 && arr[preIndex] > current) {
arr[preIndex + 1] = arr[preIndex];
preIndex--;
}
arr[preIndex + 1] = current;
}
return arr;
}
复制代码


**降序 insertDeSort()**

insertDeSort = arr => {
let current, preIndex;
for (let i = 1; i < arr.length; i++) {
current = arr[i];
preIndex = i - 1;
while (preIndex >= 0 && arr[preIndex] < current) {
arr[preIndex + 1] = arr[preIndex];
preIndex--;
}
arr[preIndex + 1] = current;
}
return arr;
}
复制代码


004.数组去重
========

arrDemp1 = arr => {
let newArr = [];
let m = {};
for (let i = 0; i < arr.length; i++) {
let n = arr[i];
if (m[n]) {

} else {  
  newArr.push(arr[i]);  
  m[n] = true;  
}  

}
return newArr;
}

//遍历数组法
arrDemp2 = arr => {
let temp = [];
for (let i = 0; i < arr.length; i++) {
//indexOf()方法可返回某个指定的字符串或数组值在字符串或数组中首次出现的位置,若不在其中则返回-1
if (temp.indexOf(arr[i]) === -1)
temp.push(arr[i]);
}
return temp;
}

//排序法
arrDemp3 = arr => {
let temp = [];
arr.sort();
temp.push(arr[0]);
//因为数组已经经过排序,所以重复元素一定相邻,判断当前数组第i个元素与temp的最后一个元素是否相等,不相等时才复制元素
for (let i = 1; i < arr.length; i++) {
if (arr[i] != temp[temp.length - 1])
temp.push(arr[i]);
}
return temp;
}

//对象法
arrDemp4 = arr => {
let temp = [];
let json = {};
//将当前数组的元素值当作对象的属性,遍历数组,比对对象,如果对象的这个属性不存在则将当前数组元素复制到临时数组,并添加该属性且将属性值赋值为1
for (let i = 0; i < arr.length; i++) {
if (!json[arr[i]]) {//如果对象没有该属性
temp.push(arr[i]);
json[arr[i]] = 1;//添加属性,将属性值赋值为1
}
}
return temp;
}
复制代码


也可以使用ES6中的new Set,一步到位

let arr = [1,2,3,5,4,5,4,3,6]
let arrDemp = new Set(arr) //arrDemp是一个对象
let newArr = [...arrDemp] //把arrDemp转化成数组
console.log(newArr);
复制代码


005.数组对象去重
==========

将对象数组中属性相同的项去重

/*

  • objArr 对象数组
  • para 将要进行去重的字段(String类型)
    */
    objArrDemp1 = (objArr, para) => {
    let result = [];
    let temp = {};
    for (let i = 0; i < objArr.length; i++) {
    let parameter = objArr[i][para];
    if (temp[parameter]) {
    continue;//不继续执行接下来的代码,跳转至循环开头
    }
    temp[parameter] = true;//为temp添加此属性(parameter)且将其值赋为true
    result.push(objArr[i]);//将这一项复制到结果数组result中去
    }
    return result;
    }

objArrDemp2 = (objArr, para) => {
let hash = {};
//reduce方法有两个参数,第一个参数是一个callback,用于针对数组项的操作;第二个参数则是传入的初始值,这个初始值用于单个数组项的操作。
objArr = objArr.reduce(function (item, next) {//这是针对数组项操作的函数,对于每个数组项,reduce方法都会将其调用一次
hash[next[para]] ? '' : hash[next[para]] = true && item.push(next);
return item;
}, []);//初始值是一个空对象,使用reduce方法返回的是空对象通过叠加执行之后的结果
return objArr;
}

// 测试数据:
let objArr = [{ name: 'a', age: 1 }, { name: 'a', age: 2 }, { name: 'b', age: 2 }]
console.log(objArrDemp1(objArr,'name')); // [ { name: 'a', age: 1 }, { name: 'b', age: 2 } ]
console.log(objArrDemp1(objArr,'age')); // [ { name: 'a', age: 1 }, { name: 'a', age: 2 } ]
复制代码


006.统计数组中各个元素出现的次数
==================

staArrNum = arr => {
let obj = {};
for (let i = 0; i < arr.length; i++) {
let m = arr[i];
if (obj.hasOwnProperty(m)) {
obj[m] += 1;
} else {
obj[m] = 1;
}
}
return obj;
}

// 测试数据
let arr = [1, 2, 3, 6, 5, 3, 2, 1, 2, 3, 2, 1]
console.log(staArrNum(arr)); // { '1': 3, '2': 4, '3': 3, '5': 1, '6': 1 }
复制代码


007.在数组中找指定的元素,返回下标
===================

arrFinNum = function (arr,num) {
let index = -1;
for (let i = 0; i < arr.length; i++) {
if (num == arr[i]) {
index = i;
break;
}
}
return index;
}

// 测试数据
let arr = [1,2,3,4,5,6]
console.log(arrFinNum(arr,4)); // 3
复制代码


008.删除数组中的元素
============

delArrNum = (arr,val) => {
let index = arrFinNum(arr, val) //调用了前面自行添加的arrFinNum方法
if (index != -1) {
return arr.splice(index, 1);
}
}
复制代码


**示例**

arrFinNum = (arr, num) => {
let index = -1;
for (let i = 0; i < arr.length; i++) {
if (num == arr[i]) {
index = i;
break;
}
}
return index;
}

delArrNum = (arr,val) => {
let index = arrFinNum(arr, val) //调用了前面自行添加的arrFinNum方法
if (index != -1) {
return arr.splice(index, 1);
}
}

// 测试数据
let arr = [1, 2, 3, 4, 5, 6]
console.log(delArrNum(arr,2)); // [ 2 ]
复制代码


009.二分查找
========

//非递归实现
binarySearch = (arr, key) => {
let high = arr.length - 1,
low = 0;
while (low <= high) {
let m = Math.floor((high + low) / 2);
if (arr[m] == key) {
return m;
}
if (key > arr[m]) {
low = m + 1;
} else {
high = m - 1;
}
}
return false;
}

// 测试数据
let arr = [-1, 1, 3, 4, 5, 8, 32, 234, 12, 42];
console.log(binarySearch(arr, 4));
复制代码


//递归实现
binarySearch = (arr, low, high, key) => {
if (low > high) {
return -1;
}
let mid = parseInt((high + low) / 2);
if (arr[mid] == key) {
return mid;
} else if (arr[mid] > key) {
high = mid - 1;
return binarySearch(arr, low, high, key);
} else if (arr[mid] < key) {
low = mid + 1;
return binarySearch(arr, low, high, key);
}
};

// 测试数据
let arr = [-1, 1, 3, 4, 5, 8, 32, 234, 12, 42];
console.log(binarySearch(arr, 0, 13, 5));
复制代码


010.对象处理为数组对象
=============

/**

  • obj 需要处理的对象
    */
    objToArrObj = obj => {
    let arr = []
    for(let i in obj){
    arr.push({[i]:obj[i]})
    }
    return arr
    }

// 测试数据
let obj = {20180410: 5, 20180411: 13, 20180412: 26, 20180413: 16}
console.log(objToArrObj(obj));
/*
[
{ 20180410: 5 },
{ 20180411: 13 },
{ 20180412: 26 },
{ 20180413: 16 }
]
*/
复制代码


011.通过键查找对象数组中对应的下标、键、值
=======================

/**

  • arr 对象数组
  • index 要查找的键名
    */
    objArrHandle = (arr,keyName) => {
    let sub = arr.findIndex(item=>item[keyName])
    let obj = arr[sub]
    let key = Object.keys(obj)[0]
    let value = obj[Object.keys(obj)]
    return '下标:'+sub+' 键:'+key+' 值:'+value
    }

// 测试数据
let arr = [{ 20180410: 5 },{ 20180411: 13 },{ 20180412: 26 },{ 20180413: 16 }]
console.log(objArrHandle(arr,20180412)); // 下标:2 键:20180412 值:26

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,784评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,745评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,702评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,229评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,245评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,376评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,798评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,471评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,655评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,485评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,535评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,235评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,793评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,863评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,096评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,654评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,233评论 2 341

推荐阅读更多精彩内容