处理字符串和数组的一些方法(updated at 2017-06-04)

多维数组转换为一维数组

1
2
3
var arr = [[1],[2,3],[4]];
var result = [].concat.apply([], arr);
console.log(result); // [ 1, 2, 3, 4 ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var arr1 = [1, [2, [3, 4]], 5, [6]];
var arr2 = [1, 2, 3, 4, [5, 6,[7,[8,[9,10]]]]];

function mergeArray(arr, dimension){
if(!dimension || dimension < 2){
console.log('Dimension should be greater or equal to 2');
return;
}
while(dimension >= 2){
arr = [].concat.apply([], arr);
dimension --;
}
return arr;
}

mergeArray(arr1,3)
mergeArray(arr2,5)

从数组中随机获取某个元素

直接获取:

var rand = myArray[Math.floor(Math.random() * myArray.length)];

原型链中添加方法获取:

1
2
3
Array.prototype.randomElement = function () {
return this[Math.floor(Math.random() * this.length)]
}

在原型链中手动添加了一个属性, 因此如果要获取内置数组方法时, 注意需要使用hasOwnProperty:

1
2
3
4
5
for (var prop in myArray) {
if (myArray.hasOwnProperty(prop)) {
//...
}
}

从数组中随机获取多个元素

可以先将数组打乱, 再获取其中连续的一段:

1
2
3
4
5
6
var numbers = ['1','2','4','5','6','7','8','9','10'];
numbers.sort(() => 0.5 - Math.random());
var sliced = numbers.slice(0, 4);

console.log(sliced);
console.log(numbers);

将类数组对象转化为数组

开发过程中有时会遇到需要操作类数组对象(array-like objects)的情况, 但无法对其使用数组方法, 因此很多时候需要把类数组对象转化为数组以便于操作, 常见的类数组对象有: arguments(函数参数), NodeList… 可以利用以下三种方法对类数组对象进行转化:

  • Array.from()
  • ... (spread operator)
  • Array.prototype.slice.call()

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
function listFrom() {
return Array.from(arguments);
}
function listSpread() {
return [...arguments];
}
function listSlice() {
return Array.prototype.slice.call(arguments);
}

const list1 = listFrom(1, 2, 3); // [1, 2, 3]
const list2 = listSpread(1, 2, 3); // [1, 2, 3]
const list3 = listSlice(1, 2, 3); // [1, 2, 3]

使用数组方法的另一种方式

例:

1
2
3
4
5
function square(n) {
return n * n;
}

const arr = [4, 8]

现在要对数组arr中的每一个元素执行平方操作, 常用的操作方式是: arr.map(square);
如果想要像underscore.js或者lodash中那样的方式使用数组方法, 可以使用以下方式:

  • Array.prototype.map.call()

  • [].map.call()

应用到例子中就是:

  • Array.prototype.map.call(arr, square)

  • [].map.call(arr, square)

组合字符串最快的方式

根据JSPerf上的标准, +=是组合字符串最快的方式. 不过或许不适用于所有浏览器版本.

如果要在DOM中实现字符串的组合, 似乎事先将字符串组合好, 再添加到DOM中是比一个一个添加更好的选择. 不过最好还是根据实际情况, 自己进行测试.

参考

扩展

在字符串中替换部分字母

在JavaScript, 字符串不可变(immutable), 因此不可以直接在原字符串本身执行替换.
可以手动在String的原型链中定义replaceAt()方法:

1
2
3
4
5
6
7
String.prototype.replaceAt = function(index, replacement) {
return this.substr(0, index) + replacement + this.substr(index + replacement.length);
// return this.substr(0, index) + replacement + this.substr(index + 1, this.length);
}

var greet="Hello World";
console.log(greet.replaceAt(2, "!!")); // 输出: He!!o World

重复输出字符串内容

1
2
3
4
5
6
7
8
9
10
11
String.prototype.repeatify = String.prototype.repeatify || function(times) {
var str = '';

for (var i = 0; i < times; i++) {
str += this;
}

return str;
};

console.log('hello'.repeatify(3)); // hellohellohello

加入String.prototype.repeatify ||以测试是否已定义过该方法, 如果没有, 则添加, 如果已定义, 则不添加, 使用原定义内容.