然后返回剩下的元素,若设置关键字N

1.信息获取Size()函数能够获取数组的相关信息。不设置关键字是,函数返回变量的基本信息:第一个返回值是变量的维数N_dims,但当变量是敞亮或未定义是返回值为0;第二个
到第N_dims+1个返回值依次对应每一维数值;倒数第二个返回值是数组类型代码;最后一个返回值是元素总个数。若设置关键字N_Dimensions、N_Elements、Dimensions、Tname和Type,则依次返回数组的维数、元素个数、每一维的位数、类型名称和类型代码信息。IDL>
var=5IDL> ;依次为0维 整数 共1个元素IDL> print,size 0 2 1IDL>
str=[‘abc’,’def’]IDL> ;依次对应1维 1维上2个元素 字符串型
共两个元素IDL> print,size 1 2 7 2IDL> arr=findgenIDL>
help,size(arr,/N_elements) LONG = 30IDL> help,size(arr,/Dimensions)
LONG =
Array[2]2,.条件查询函数WHERE()能返回数组中满足指定条件的元素下标。调用格式为Result=Where(数组表达式[,count][,Complement=变量1][,/L64][,NCOMPLEMENT=变量2])其中,关键字count返回符合指定条件的元素个数;变量1为不满足条件的数组元素下标;变量2为不满足条件的数组元素个数。IDL>
arr=indgenIDL> print,arr 0 1 2 3 4 5 6 7 8 9 IDL> result=where(arr
GT 5,count,complement=res_c,ncomplement=res_n)IDL> print,count
4IDL> print,result 6 7 8 9IDL> print,res_c 0 1 2 3 4 5IDL>
print,res_c 0 1 2 3 4 5IDL> print,res_n 63.调整大小
Reform()函数:可以在不改变数组元素个数的前提下改变数组的维数。调用格式为Result=Reform(Array,D1[,…,D8][,关键字])IDL>
arr=indgenIDL> b=reform(arr,200,5)IDL> c=arr[0,*,*]IDL>
help,cC INT = Array[1, 10, 10]IDL> d=reform(arr[0,*,*])IDL>
help,dD INT = Array[10, 10]
Rebin()函数:可以修改数组大小,修改后数组的行数或列数必须是原数组行数或列数的整数倍。默认抽样算法是双线性内插法。调用格式为Result=Rebin(数组,D1[,…,D8][,/Simple])其中,Sample为使用最近临值抽样算法。IDL>
arr=[[0,6],[2,8]]IDL> print,arr 0 6 2 8IDL> print,rebin 0 3
6 6 1 4 7 7 2 5 8 8 2 5 8 8IDL> print,rebin(arr,4,4,/sample) 0 0 6 6
0 0 6 6 2 2 8 8 2 2 8 8IDL> print,rebin% REBIN: Result dimensions
must be integer factor of original dimensions% Execution halted at:
$MAIN$
Congrid()函数:可以将数组调整为同维任意大小。处理以为或者二位数组时,默认算法是最近邻重采样;处理三维数组时,算法是双线性内插。在对数组进行缩小操作时,Rebin()函数进行差值处理;Congrid()函数仅进行重采样。调用格式为Result=Congid(数组,X,Y,Z[,关键字])其中,关键字INTERP为抽样采用线性内插;关键字CUBIC为卷积内插法IDL>
print,arr 0 6 2 8IDL> print,congrid 0 6 6 0 6 6 2 8 8 2 8 8
Interpolate()函数:可以将数组调整到同维任意大小,并支持任意定位差值。调用格式为Interpolate(数组,X[,Y[,Z]][,关键字])其中,X[,Y[,Z]]为待调整数组下标索引,可以是单个变量或数组。若X为0.5,则表示计算下标[0]和小标[1]中间位置的数值。关键字选择GRID为采用网格差值方式生成插值点;否则,采用线性内插方式。关键字Missing为插值点坐标超出数组自身坐标范围时赋予该值。IDL>
arr=findgenIDL> print,arr 0.000000 1.00000 2.00000 3.00000IDL>
print,interpolate(arr,[0,.5,1.5],[0,.5,1.5]) 0.000000 1.50000
3.00000IDL> print,interpolate(arr,[0,.5,1.5],[0,.5,1.5],/grid)
0.000000 0.500000 1.00000 1.00000 1.50000 2.00000 2.00000 2.50000
3.00000IDL>
print,interpolate(arr,[0,.5,1.5],[0,.5,1.5],/grid,missing=0)
0.000000 0.500000 0.000000 1.00000 1.50000 0.000000 0.000000 0.000000
0.0000004.数组反转Reverse()函数可以对数组进行翻转。调用格式为Result=Reverse(数组,index[,/overwrite])其中,关键字Index为数组的维数索引IDL>
arr=indgenIDL> print,arr 0 1 2 3IDL> ;行反转IDL> print,reverse
1 0 3 2IDL> ;列反转IDL> print,reverse 2 3 0
15.数组转置Result=Transpose其中关键字P为需要调整维数的数组列表,如不设置,则完全反转IDL>
arr=indgenIDL> help,arrARR INT = Array[2, 3, 4]IDL>
help,transpose(arr,[0,2,1]) INT = Array[2, 4, 3]IDL>
help,transpose(arr,[2,1,0]) INT = Array[4, 3, 2]IDL>
help,transpose INT = Array[4, 3, 2]6.数组旋转
Rotate()函数:可以以90°的整倍数角度对数组进行旋转操作。调用格式为Result=Rotate(数组,Direction)其中,Direction取值范围为0~7。对应的图像旋转方式见表Rotate函数Direction参数说明
Direction 是否转置 顺时针旋转角度 旋转后坐标X1 旋转后坐标Y10 否 0° X0
Y01 否 90 ° Y0 -X0 2 否 180 ° -X0 -Y03 否 270 ° -Y0 X0 4 是 0 ° Y0 X05
是 90 ° -X0 Y0 6 是 180 ° -Y0 -X0 7 是 270 ° X0
-Y0Rotate()函数的调用示例代码如下:IDL> arr=indgenIDL> print,arr 0
1 2 3 4 5IDL> print,rotate 4 2 0 5 3 1IDL> print,rotate 5 4 3 2 1
0
函数:可以以任意角度对图像进行旋转,同时能进行放大和缩小控制。调用格式为Result=Rot(数组,Angle,[Mag,X0,Y0],[关键字])其中,Angle为数组旋转的角度,单位为度;Mag为放大的倍数;X0为旋转中心的X坐标,默认为列中心;Y0为旋转中心的Y坐标,默认为行中心;关键字选择PIVOT可控制旋转后点是否仍然在原图像中的位置,不设置则点在图像的中心位置。IDL>
data=bytscl)IDL> tv,dataIDL>
tv,rot(data,33,1.5,/interp)7.数组平移Shift()函数可以基于指定平移量S1…Sn对数组进行第1…n维平移,其中,Si值为正表示向前平移;Si为负表示向后平移。调用格式为Result=Shift(数组,S1…Sn)IDL>
arr=indgenIDL> print,arr 0 1 2 3 4IDL> print,shift 4 0 1 2
3IDL> print,shift 1 2 3 4 0IDL> arr=indgenIDL> print,shift 14
15 0 1 2 3 4 5 6 7 8 9 10 11 12 13IDL> print,shift 15 12 13 14 3 0 1
2 7 4 5 6 11 8 9
108.数组排序Sort()函数实现数组的排序功能,返回结果是排序后数组的下标索引。调用格式为Result=Sort(数组[,/L64])IDL>
arr=[5,2,1,3,4]IDL> ;数组排序后索引IDL> print,sort 2 1 3 4
0IDL> ;排序后数组IDL> print,arr[sort]188金宝搏, 1 2 3 4
59.求不同值Uniq()函数能返回数组中相邻元素不同值的索引。注意,该函数只能发现相邻值;若不相邻,则会认为是两个值。如果先对数组进行排序,则可求出数组中包含的不同值。调用格式为Result=Uniq(数组[,Index])IDL>
arr=[5,2,1,3,4]IDL> ;数组排序后索引IDL> print,sort 2 1 3 4
0IDL> ;排序后数组IDL> print,arr[sort] 1 2 3 4 5IDL>
arr=[1,2,1,3,3]IDL> print,arr[uniq] 1 2 1 3IDL>
print,arr[uniq(arr[sort] 2 1
310.判断数组Array_Equal其中,Result返回值为0或1;关键字No_TypeConv用于将两数组转换为同一类型,来判断数组元素是否相同;为1时,数组可直接比较,不转换数据类型。IDL>
arr1=[1,1]IDL> arr2=[1b,1b]IDL> print,array_equal(arr1,arr2)
1IDL> print,array_equal(arr1,arr2,/no_typeconv)
011.求元素个数IDL> arr=intarrIDL> print,n_elements
4012.求最大值Max()函数返回数组元素中的最大值。调用格式为Result=Max(数组
[,关键字],min=变量1)其中Result返回数组的最大值;变量1返回数组的最小值IDL>
arr=findgenIDL> print,arr 0.000000 1.00000 2.00000 3.00000 4.00000
5.00000 6.00000 7.00000 8.00000 9.00000 10.0000 11.0000IDL>
print,max(arr,min=minval) 11.0000IDL> print,minval
0.00000013.求最小值Min函数类似,但它返回数组元素的最小值。调用格式为Result=min(数组
[,关键字],max=变量1)其中,Result返回数组最小值;变量1返回数组最大值。IDL>
arr=findgenIDL> print,min(arr,max=maxval) 0.000000IDL>
print,maxval
11.000014.求和Total()函数可以计算数组中所有或部分元素的和。调用格式为Result=Total(数组,Dimension,[,关键字])其中,Result返回数组元素求和结果;Dinension为求和元素的行列控制;Cumulative返回同大小数组,数组第i个元素值为0~i元素值的和;Double返回双精度值;integer返回整型值;preserve_type结果类型与原数组类型一致,设置该关键字时,double等关键字无效。IDL>
arr=findgenIDL> print,arr 0.000000 1.00000 2.00000 3.00000 4.00000
5.00000IDL> ;数组求和IDL> print,total 15.0000IDL>
;新数组,每个值为原数组0-i个元素的和IDL> print,total(arr,/cumulative)
0.000000 1.00000 3.00000 6.00000 10.0000 15.0000IDL> ;按行求和IDL>
print,total 1.00000 5.00000 9.00000IDL> ;按列求和IDL> print,total
6.00000
9.0000015.乘积计算Product()函数计算数组中所有或部分元素的乘积。调用格式为Result=product(数组,Dimension,[,关键字])其中,关键字与total函数的基本一致。IDL>
arr=findgen+1IDL> print,arr 1.00000 2.00000 3.00000 4.00000 5.00000
6.00000IDL> ;数组元素乘积IDL> print,product 720.00000IDL>
;新数组,每个值为原数组0-i个元素的乘积IDL>
print,product(arr,/cumulative) 1.0000000 2.0000000 6.0000000 24.000000
120.00000 720.00000IDL> ;按行求乘积IDL> print,product 2.0000000
12.000000 30.000000IDL> ;按列求乘积IDL> print,product 15.000000
48.00000016.阶乘计算Factorial()函数计算数N的阶乘,即N!。调用格式为Result=factorial(数组,[,关键字])其中,关键字Stirling返回结果为Stirling近似值,计算公式为N!=√[N/e]NIDL>
;求5的阶乘IDL> print,factorial
120.0000017.平均值计算Mean()函数计算数组元素平均值。调用格式为Result=Mean(数组,[,关键字])IDL>
arr=[65,63,67,64]IDL> print,mean
64.750018.方差计算Variance()函数计算数组的方差。调用格式为Result=Variance(数组,[,关键字])IDL>
arr=[1,1,1,2,5]IDL> print,variance
3.0000019.标准差计算Result=Stddev(数组,[,关键字])IDL>
arr=[1,1,1,2,5]IDL> print,stddev
1.7320520.平均值、方差、倾斜度及频率曲线峰值计算Moment()函数可以计算数组的平均值、方差、倾斜度及频率曲线峰态。调用格式为Result=Moment(数组,[,关键字])IDL>
arr=[1,1,1,2,5]IDL> print,moment 2.00000 3.00000 0.923760 -1.13333

  本系列主要记录javascript中,新手比较容易搞错的地方。

(1)filter

  filter也是一个常用的操作,它用于把Array的某些元素过滤掉,然后返回剩下的元素。

  和map()类似,Arrayfilter()也接收一个函数。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素。

  例如,在一个Array中,删掉偶数,只保留奇数,可以这么写:

  var arr = [1, 2, 4, 5, 6, 9, 10, 15];
  var r = arr.filter(function (x) {
      return x % 2 !== 0;
  });
  r; // [1, 5, 9, 15]

  把一个Array中的空字符串删掉,可以这么写:

  var arr = ['A', '', 'B', null, undefined, 'C', '  '];
  var r = arr.filter(function (s) {
      return s && s.trim(); // 注意:IE9以下的版本没有trim()方法
  });
  r; // ['A', 'B', 'C']

  可见用filter()这个高阶函数,关键在于正确实现一个“筛选”函数。

(2)sort排序算法

  排序也是在程序中经常用到的算法。无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小。如果是数字,我们可以直接比较,但如果是字符串或者两个对象呢?直接比较数学上的大小是没有意义的,因此,比较的过程必须通过函数抽象出来。通常规定,对于两个元素x和y,如果认为x
< y,则返回-1,如果认为x == y,则返回0,如果认为x >
y,则返回1,这样,排序算法就不用关心具体的比较过程,而是根据比较结果直接排序。

  JavaScript的Array的sort()方法就是用于排序的,但是排序结果可能让你大吃一惊:

  // 看上去正常的结果:
    [‘Google’, ‘Apple’, ‘Microsoft’].sort(); // [‘Apple’,
‘Google’, ‘Microsoft’];

  // apple排在了最后:
    [‘Google’, ‘apple’, ‘Microsoft’].sort(); // [‘Google’,
‘Microsoft”, ‘apple’]

  // 无法理解的结果:
    [10, 20, 1, 2].sort(); // [1, 10, 2, 20]
  第二个排序把apple排在了最后,是因为字符串根据ASCII码进行排序,而小写字母a的ASCII码在大写字母之后。

  第三个排序结果是什么鬼?简单的数字排序都能错?

  这是因为Array的sort()方法默认把所有元素先转换为String再排序,结果’10’排在了’2’的前面,因为字符’1’比字符’2’的ASCII码小。

  如果不知道sort()方法的默认排序规则,直接对数字排序,绝对栽进坑里!
  幸运的是,sort()方法也是一个高阶函数,它还可以接收一个比较函数来实现自定义的排序。
  要按数字大小排序,我们可以这么写:
    var arr = [10, 20, 1, 2];
    arr.sort(function (x, y) {
    if (x < y) {
    return -1;
    }
    if (x > y) {
    return 1;
    }
    return 0;
  }); // [1, 2, 10, 20]
  如果要倒序排序,我们可以把大的数放前面:
    var arr = [10, 20, 1, 2];
    arr.sort(function (x, y) {
    if (x < y) {
    return 1;
    }
    if (x > y) {
    return -1;
    }
  return 0;
  }); // [20, 10, 2, 1]

需要注意的是:sort()方法会直接对Array进行修改!

(3)函数作为返回值

  高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。
  我们来实现一个对Array的求和。通常情况下,求和的函数是这样定义的:
    function sum(arr) {
    return arr.reduce(function (x, y) {
    return x + y;
    });
    }
    sum([1, 2, 3, 4, 5]); // 15
  但是,如果不需要立刻求和,而是在后面的代码中,根据需要再计算怎么办?可以不返回求和的结果,而是返回求和的函数!
    function lazy_sum(arr) {
    var sum = function () {
    return arr.reduce(function (x, y) {
    return x + y;
    });
    }
    return sum;
  }
  当我们调用lazy_sum()时,返回的并不是求和结果,而是求和函数:
    var f = lazy_sum([1, 2, 3, 4, 5]); // function sum()
  调用函数f时,才真正计算求和的结果:
    f(); // 15
  在这个例子中,我们在函数lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量

都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。
  请再注意一点,当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数:
  var f1 = lazy_sum([1, 2, 3, 4, 5]);
  var f2 = lazy_sum([1, 2, 3, 4, 5]);
  f1 === f2; // false
  f1()和f2()的调用结果互不影响。

(4)闭包

  注意到返回的函数在其定义内部引用了局部变量arr,所以,当一个函数返回了一个函数后,其内部的局部变量还被新函数引用,所以,闭包用起来简单,实现起来可不容易。

  另一个需要注意的问题是,返回的函数并没有立刻执行,而是直到调用了f()才执行。我们来看一个例子:

  function count() {
      var arr = [];
      for (var i=1; i<=3; i++) {
        arr.push(function () {
            return i * i;
        });
    }
    return arr;
}

var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];

在上面的例子中,每次循环,都创建了一个新的函数,然后,把创建的3个函数都添加到一个Array中返回了。

你可能认为调用f1()f2()f3()结果应该是149,但实际结果是:

f1(); // 16
f2(); // 16
f3(); // 16

全部都是16!原因就在于返回的函数引用了变量i,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i已经变成了4,因此最终结果为16

返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变:

function count() {
    var arr = [];
    for (var i=1; i<=3; i++) {
        arr.push((function (n) {
            return function () {
                return n * n;
            }
        })(i));
    }
    return arr;
}

var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];

f1(); // 1
f2(); // 4
f3(); // 9

注意这里用了一个“创建一个匿名函数并立刻执行”的语法:

(function (x) {
    return x * x;
})(3); // 9

理论上讲,创建一个匿名函数并立刻执行可以这么写:

function (x) { return x * x } (3);

但是由于JavaScript语法解析的问题,会报SyntaxError错误,因此需要用括号把整个函数定义括起来:

(function (x) { return x * x }) (3);

通常,一个立即执行的匿名函数可以把函数体拆开,一般这么写:

(function (x) {
    return x * x;
})(3);

说了这么多,难道闭包就是为了返回一个函数然后延迟执行吗?

当然不是!闭包有非常强大的功能。举个栗子:

在面向对象的程序设计语言里,比如Java和C++,要在对象内部封装一个私有变量,可以用private修饰一个成员变量。

在没有class机制,只有函数的语言里,借助闭包,同样可以封装一个私有变量。我们用JavaScript创建一个计数器:

'use strict';

function create_counter(initial) {
    var x = initial || 0;
    return {
        inc: function () {
            x += 1;
            return x;
        }
    }
}

它用起来像这样:

var c1 = create_counter();
c1.inc(); // 1
c1.inc(); // 2
c1.inc(); // 3

var c2 = create_counter(10);
c2.inc(); // 11
c2.inc(); // 12
c2.inc(); // 13

在返回的对象中,实现了一个闭包,该闭包携带了局部变量x,并且,从外部代码根本无法访问到变量x。换句话说,闭包就是携带状态的函数,并且它的状态可以完全对外隐藏起来。

闭包还可以把多参数的函数变成单参数的函数。例如,要计算xy可以用Math.pow(x, y)函数,不过考虑到经常计算x2或x3,我们可以利用闭包创建新的函数pow2pow3

function make_pow(n) {
    return function (x) {
        return Math.pow(x, n);
    }
}

// 创建两个新函数:
var pow2 = make_pow(2);
var pow3 = make_pow(3);

pow2(5); // 25
pow3(7); // 343

You may also like...

发表评论

电子邮件地址不会被公开。 必填项已用*标注

相关文章

网站地图xml地图