9159金沙游艺场


c#调用腾讯云API的实例
9159金沙游艺场 11
——–驱动开发之 ObReferenceObjectByName() 故障排查——–

有趣的JavaScript原生数组函数

优雅的数组降维——Javascript中apply方法的妙用

2016/02/18 · JavaScript
· apply,
数组

原文出处:
ralph_zhu   

将多维数组(尤其是二维数组)转化为一维数组是业务开发中的常用逻辑,除了使用朴素的循环转换以外,我们还可以利用Javascript的语言特性实现更为简洁优雅的转换。本文将从朴素的循环转换开始,逐一介绍三种常用的转换方法,并借此简单回顾Array.prototype.concat方法和Function.prototype.apply方法。
以下代码将以把二维数组降维到一维数组为例。

  1. 朴素的转换

JavaScript

function reduceDimension(arr) { var reduced = []; for (var i = 0; i
< arr.length; i++) { for (var j = 0; j < arr[i].length; j++) {
reduced.push(arr[i][j]); } } return reduced; }

1
2
3
4
5
6
7
8
9
function reduceDimension(arr) {
    var reduced = [];
    for (var i = 0; i < arr.length; i++) {
        for (var j = 0; j < arr[i].length; j++) {
            reduced.push(arr[i][j]);
        }
    }
    return reduced;
}

此方法思路简单,利用双重循环遍历二维数组中的每个元素并放到新数组中。

 

  1. 利用concat转换
    先来回顾一下MDN上对于该方法的介绍:
    “concat creates a new array consisting of the elements in the object on
    which it is called, followed in order by, for each argument, the
    elements of that argument (if the argument is an array) or the argument
    itself (if the argument is not an array).”

即如果concat方法的参数是一个元素,该元素会被直接插入到新数组中;如果参数是一个数组,该数组的各个元素将被插入到新数组中;将该特性应用到代码中:

JavaScript

function reduceDimension(arr) { var reduced = []; for (var i = 0; i
< arr.length; i++){ reduced = reduced.concat(arr[i]); } return
reduced; }

1
2
3
4
5
6
7
function reduceDimension(arr) {
    var reduced = [];
    for (var i = 0; i < arr.length; i++){
        reduced = reduced.concat(arr[i]);
    }
    return reduced;
}

arr的每一个元素都是一个数组,作为concat方法的参数,数组中的每一个子元素又都会被独立插入进新数组。
利用concat方法,我们将双重循环简化为了单重循环。

 

  1. 利用apply和concat转换
    按照惯例,先来回顾一下MDN上对于apply方法的介绍:
    “The apply() method calls a function with a given this value and
    arguments provided as an array.”

即apply方法会调用一个函数,apply方法的第一个参数会作为被调用函数的this值,apply方法的第二个参数(一个数组,或类数组的对象)会作为被调用对象的arguments值,也就是说该数组的各个元素将会依次成为被调用函数的各个参数;将该特性应用到代码中:

function reduceDimension(arr) { return
Array.prototype.concat.apply([], arr); }

1
2
3
function reduceDimension(arr) {
    return Array.prototype.concat.apply([], arr);
}

arr作为apply方法的第二个参数,本身是一个数组,数组中的每一个元素(还是数组,即二维数组的第二维)会被作为参数依次传入到concat中,效果等同于[].concat([1,2],
[3,4], [5,6])。
利用apply方法,我们将单重循环优化为了一行代码,很简洁有型有木有啊~

读者也可参照本文思路,自己利用递归实现N维数组降维的逻辑。

3 赞 8 收藏
评论

图片 1

jQuery对象是用来储存与处理dom元素的,它主要依赖于setArray方法来设置与维护长度与索引,而setArray的参数要求是一个数组,因此makeArray的地位非常重要。这方法保证就算没有参数也要返回一个空数组。
Prototype.js的$A方法

计算.reduce和.reduceRight

复制代码 代码如下:

[void 0, null, false, ”, 1].filter(function (value) {

您可能感兴趣的文章:

  • JavaScript中的类数组对象介绍
  • JavaScript 里的类数组对象
  • js
    用于检测类数组对象的函数方法
  • JQuery
    $.each遍历JavaScript数组对象实例
  • js使用Array.prototype.sort()对数组对象排序的方法
  • js接收并转化Java中的数组对象的方法
  • JS从非数组对象转数组的方法小结
  • javascript
    Array数组对象的扩展函数代码
  • JavaScript类数组对象转换为数组对象的方法实例分析

while (item = list.shift()) {

在标准浏览器中,好像只要对象存在length属性,就能把它转换为数组,但IE就不尽然。

    return value

//jQuery的makeArray
var makeArray = function( array ) {
var ret = [];
if( array != null ){
var i = array.length;
// The window, strings (and functions) also have ‘length’
if( i == null || typeof array === “string” || jQuery.isFunction(array)
|| array.setInterval )
ret[0] = array;
else
while( i )
ret[–i] = array[i];
}
return ret;
}

复制代码

复制代码 代码如下:

 

mootools的$A方法

 

function $A(iterable) {
if (!iterable) return [];
if (iterable.toArray) return iterable.toArray();
var length = iterable.length || 0, results = new Array(length);
while (length–) results[length] = iterable[length];
return results;
}

 

(function(){
var efficient = function(obj, offset, startWith){
return (startWith||[]).concat(Array.prototype.slice.call(obj,
offset||0));
};
var slow = function(obj, offset, startWith){
var arr = startWith||[];
for(var x = offset || 0; x >obj.length; x++){
arr.push(obj[x]);
}
return arr;
};
dojo._toArray =
dojo.isIE ? function(obj){
return ((obj.item) ? slow : efficient).apply(this, arguments);
} :
efficient;
})();

 

[Ctrl+A 全选
注:如需引入外部Js需刷新才能执行]

Array.prototype.slice.call({ 0: ‘a’, 1: ‘b’, length: 2 })

function $A(iterable){
if (iterable.item){
var l = iterable.length, array = new Array(l);
while (l–) array[l] = iterable[l];
return array;
}
return Array.prototype.slice.call(iterable);
};

    return text

复制代码 代码如下:

        text = ‘<b>’ + text + ‘</b>’

var toArray = function(){
return isIE ?
function(a, i, j, res){
res = [];
Ext.each(a, function(v) {
res.push(v);
});
return res.slice(i || 0, j || res.length);
} :
function(a, i, j){
return Array.prototype.slice.call(a, i || 0, j || a.length);
}
}()

// <- []

Ext的设计比较巧妙,功能也比较强大。它一开始就自动执行自身,以后就不用判定浏览器了。它还有两个可选参数,对生成的纯数组进行操作。
最后看dojo的_toArray,dojo的实现总是那么怪异的。
和Ext一样,后面两个参数是可选,只不过第二个是偏移量,最后一个是已有的数组,用于把新生的新组元素合并过去。

 

复制代码 代码如下:

 

Ext的toArray方法

栈和队列.pop,.push,.shift和.unshift

接着我们看看各大类库的处理:

复制代码

复制代码 代码如下:

// 遍历

console.log(b.indexOf(1))

// <- 0

每个人都知道向数组添加元素用.push。但你知道一次可以添加多个元素吗?如下[].push(‘a’,
‘b’, ‘c’, ‘d’, ‘z’)。

// <- <b>somesomethingother things</b>

 

a.reverse()

Array.prototype.map方法和上面我们提到的.forEach,.some和.every有相同的参数:.map(fn(value,
index, array), thisArgument)。

console.log(b === c)

查找.indexOf

// <- true

console.log(max)

 

复制代码

 

断言.some和.every

[9,80,3,10,5,6].sort()

    this._queue = []

var a = { foo: ‘bar’ }

array 当前数组的引用

 

 

values[7] = void 0

 

和复制不同的是,数组本身被更改。在以后的文章中我将展开对这些概念的理解,去看看如何创建一个库,如Underscore或Lo-Dash。

.splice是我最喜欢的原生数组函数之一。它允许你删除元素,插入新元素,或在同一位置同时进行上述操作,而只使用一个函数调用。注意和.concat和.slice不同的是.splice函数修改原数组。

// <- removed 13

})

 

// <- ‘awesome’

})

// <- 3

 

    { name: ‘Sam’ },

    return value

filter对每个数组元素执行一次回调函数,并返回一个由回调函数返回true的元素
组成的新数组。回调函数只会对已经指定值的数组项调用。

})

index 当前操作元素的数组索引

queue.add(1,2,3)

// <- [‘a’, ‘b’]

    { name: ‘George’ },

 

模型映射.map

 

5 in a

复制代码

 

复制代码

        text = text.replace(‘%s’, value)

}

    if (value > max) max = value

复制代码

    return input.reduce(function (partial, value) {

Stack.prototype.next = function () {

 

concat([

像大部分排序函数一样,Array.prototype.sort(fn(a,b))需要一个包含两个测试参数的回调函数,并且要产生一下三种返回值之一:

var a = [1, 2, 5]

Array.prototype.slice能被用来将类数组对象转换为真正的数组。

[void 0, null, false, ”, 1].filter(function (value) {

用.shift或.pop能很容易遍历数组元素,并做一些操作。

 

 

 

栈和队列.pop,.push,.shift和.unshift

    console.log(‘removed’, value)

var a = [1, 1, 7, 8]

 

// <- 28

[1, ‘2’, ’30’, ‘9’].map(function (value) {

 

复制代码

format(‘some%sthing%s %s’, true, ‘some’, ‘other’, ‘things’)

 

// <- -1

in操作符

function Queue () {

list = [1,2,3,4,5,6,7,8,9,10]

走进.reverse

在JavaScript中,可以通过两种方式创建数组,构造函数和数组直接量,
其中后者为首选方法。数组对象继承自Object.prototype,对数组执行typeof操作符返回‘object’而不是‘array’。然而执行[]
instanceof
Array返回true。此外,还有类数组对象是问题更复杂,如字符串对象,arguments对象。arguments对象不是Array的实例,但却有个length属性,并且值能通过索引获取,所以能像数组一样通过循环操作。

    return this._stack.pop()

复制代码

        return partial + value

    return this.reduce(function (partial, value) {

.join和.concat的区别

stack.next()

max = -Infinity

1 in a

 

})

复制代码

 

b[3] === a && c[3] === a

// <- true

这方法将数组中的元素翻转并替换原来的元素。

用法例子:.filter(fn(value, index, array),
thisArgument)。把它想象成.Where(x => x.IsAwesome) LINQ
expression(如果你熟悉C#),或者SQL语句里面的WHERE。考虑到.filter仅返回callback函数返回真值的值,下面是一些有趣的例子。没有传递给回调函数测试的元素被简单的跳过,不会包含进返回的新书组里。

如果a在b前,则返回值小于零

    return {

复制代码

 

}

satisfied = [10, 12, 10, 8, 5, 23].some(function (value, index, array)
{

    return parseInt(value, 10)

问题的关键是in操作符检索对象的键而非值。当然,这在性能上比.indexOf快得多。

这是JavaScript原生数组方法中最简单的方法。不用怀疑,IE7和IE8不支持此方法。

 

spliced.forEach(function (value) {

相关文章

No Comments, Be The First!
近期评论
    功能
    网站地图xml地图