• IDL学习:语法基础-对象、哈希表


            本博客将介绍IDL语法基础中的对象哈希表创建及相关的操作发法哈希表、链表都可以看做对象,包含了add、reserve、Sort等方法。记录自己的学习+整理+理解 。

    1. 对象 

            对象是数据(属性)和程序(方法)封装在一起的实体。对象的功能操作或接收到外界信息后的处理操作成为方法(来自《IDL程序设计——数据可视化分析与ENVI二次开发》)。举个栗子,例如计算计算计算圆的相关性质,可以是计算圆的直径、面积、周长……        

    1.1 创建对象

            可以利用Obj_New()函数、ObjArr()函数来创建对象,语法如下:

    Result = OBJ_NEW( [ObjectClassName [, Arg1...Argn]] )

    Result = OBJARR( D1[, ..., D8] )

            ObjectClassName是指IDL提供的对象名字,IDL提供的对象形如IDLxxYYYY,xx表示类的类型,YYYY表示类的名称。例如IDLgrImage表示类为图形(gr是graphics的缩写)中的图像(Image)对象;IDLgrPDF表示类为图形(gr是graphics的缩写)中的PDF对象;IDLgrView表示类为图形(gr是graphics的缩写)中的视图(view)对象。IDL中提供对象可以分为5类:

    1.  Analysis Object Classes                        分析对象类                         简称:an
    2.  File Format Object Classes                   文件格式对象类                  简称:ff
    3.  Graphics Object Classes                       图形对象类                         简称:gr
    4.  Network Object Classes                        网络对象类                          简称:net
    5.  Miscellaneous Object Classes               其他项目类别                     简称:_、db、com等

            对象查看地址:帮助文档中 Routines (alphabetical) > Object Classes

     例子:新建一个IDLgr

    1. >>oImage = Obj_new('IDLGRIMAGE')
    2. >>help,oIMAGE
    3. OIMAGE OBJREF = <ObjHeapVar1(IDLGRIMAGE)>

    IDL8.0之后版本,也可以直接吧对象当做函数使用,直接创建新的对象,格式如下:

    Result = ObjClassName([Arg1...Argn])

    ObjClassName表示对象的名称,例如IDLgrPDF、IDLgrImage……

    1. >>oImage1 = Idlgrimage()
    2. >>help,oImage1
    3. OIMAGE1 OBJREF = <ObjHeapVar4(IDLGRIMAGE)>

    注: Arg1...Argn表示参数、属性,也可以通过对象设置属性的方法设置对象属性Setproperty。反之,获取对象属性,可以利用Getproperty

    1. >>oImage1 = Idlgrimage(Name='Hulz') ; 新建Idlgrimage的对象oImage1,Name属性值为Hulz
    2. >>oImage1.Getproperty,Name = Name
    3. >>Name
    4. Hulz
    5. >>oImage1.Setproperty,Name = 'XMU' ; 设置对象变量oImage1,Name属性值为XMU
    6. >>Name
    7. XMU

             注:对象创建后,可以利用Obj_Valid()进行验证,

    Result = OBJ_VALID( [Arg] [, /CAST] [, COUNT=variable] [, /GET_HEAP_IDENTIFIER] )

            常配合 IF (OBJ_VALID(obj)) THEN …一起使用。

    1.2 调用对象

            调用对象本质就是调用所包含的方法,对象的方法是有两大类组成,过程Produre和函数function。我的上一个博客中所讲的链表以及前面的博客中将的IDLffshape,也是一个对象,其中该对象的方法如博客中的2.2小结所示,有List::addlist::Count……这些方法都是针对链表list的操作方法。

            在以下示例中,读取 states.shp Shapefile 中的所有实体,然后调用 DestroyEntity 方法来清理所有指针(代码来自官方示例):

    1. PRO Ex_shapefile
    2. ; 代码来自官方示例程序
    3. ; 打开示例目录中的 states Shapefile
    4. myshape=Obj_new('IDLffShape', Filepath('states.shp', $
    5. SUBDIR=['examples', 'data']))
    6. ; 获取实体的数量,以便我们可以解析它们。
    7. myshape.Getproperty, N_ENTITIES=num_ent
    8. ; 阅读所有实体。 Shapefile 中的实体数组从索引零 (0) 开始。
    9. FOR x=0, (num_ent-1) DO BEGIN
    10. ; Read the entity x
    11. ; ent = myshape.Getentity(x)
    12. ent = myshape->Getentity(x)
    13. ; 清理指针
    14. ; myshape.Destroyentity, ent
    15. myshape->Destroyentity, ent
    16. ENDFOR
    17. ; 关闭 Shapefile.
    18. Obj_destroy, myshape
    19. END

            下面一段为读取Shape文件存放的数据

    1. FUNCTION Read_shape_disp,Files
    2. ;COMPILE_OPT idl2
    3. ; 选取shape文件
    4. Tmp = Strpos(File_basename(Files),'.shp')
    5. Shp_Files = Files(Where(Tmp > 0))
    6. ; Shape文件个数
    7. N_Files = N_elements(Shp_Files)
    8. attr_values = !null ; 空矩阵,存放数据
    9. FOR index = 0L, N_Files-1 DO BEGIN
    10. ;读取shp文件的信息
    11. oshp=Obj_new('IDLffShape',Shp_Files(index))
    12. IF ~Obj_valid(oshp) THEN Return,0
    13. oshp->Getproperty,n_entities=n_ent,$ ;记录个数
    14. Attribute_info=attr_info,$ ;属性信息,结构体, name为属性名
    15. ATTRIBUTE_NAMES = attr_names, $
    16. n_attributes=n_attr,$ ;属性个数
    17. Entity_type=ent_type ;记录类型
    18. ;循环中,读取每条shp记录
    19. FOR i = 0, n_ent-1 DO BEGIN
    20. ent = oshp->Getentity(i, /ATTRIBUTES) ;第i条记录,获取数据
    21. attr_values = [attr_values, (*(ent.ATTRIBUTES)).(0)]
    22. ENDFOR
    23. ENDFOR
    24. Value_Ave = Mean(attr_values,/Nan) ; 计算均值
    25. Return,Value_Ave
    26. END

     1.3 对象常用函数        

            为了更方便使用对象,官方还给出了几个对象常用函数,常见的函数有:Obj_Class()、Obj_HasMethod()、Obj_IsA()。

    1.3.1 Obj_Class()

            Obj_Class()函数是用来获取对象的基类或继承类的名称。

    1. >>oshp=Obj_new('IDLffShape')
    2. % Loaded DLM: SHAPEFILE.
    3. >>oshp2 = obj_Class(oshp)
    4. >>help,oshp
    5. OSHP OBJREF = <ObjHeapVar8(IDLFFSHAPE)>
    6. >>help,oshp2
    7. OSHP2 STRING = 'IDLFFSHAPE'

    1.3.2 Obj_HasMethod()

            Obj_HasMethod()函数是用来判断对象是否具备某个方法,具备该方法则输出1,反之为0

    1. >>oshp=Obj_new('IDLffShape')
    2. >>print,Obj_hasmethod(oshp,'Getentity')
    3. 1
    4. >>print,Obj_hasmethod(oshp,'AAAAA');胡编的方法AAAAA
    5. 0

    1.3.3 Obj_IsA()

            Obj_IsA()函数是用来对象是否是某个类的实例,是,则输出1,反之为0.

    1. >>oshp=Obj_new('IDLffShape')
    2. >>print,Obj_IsA(oSHP,'IDLffShape')
    3. 1
    4. >>print,Obj_IsA(oSHP,'IDLgrImage')
    5. 0

    1.4 销毁对象

            利用OBJ_DESTROY过程销毁对象,语法如下:

    ​OBJ_DESTROY, ObjRef [, Arg1, …, Argn]

            若销毁所有现有的指针堆变量使用命令: OBJ_DESTROY, OBJ_VALID()

    2. 哈希表

             哈希表是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。(来源于:百度百科)

            注:哈希表可以视为一个官方设定的最基础的对象,从角度上,学习哈希表、链表,更容易理解它们复杂的操作方法。

    1. >>A = Obj_new('HASH')
    2. >>A
    3. {
    4. }
    5. >>help,A
    6. A HASH <ID=12 NELEMENTS=0>
    7. >>B = Hash()
    8. >>help,B
    9. B HASH <ID=23 NELEMENTS=0>

             其中,两种方法获取的哈希表是一样的,ID是系统分配的,任何变量都不一致

    2.1 创建哈希表

            可以利用函数Hash()创建哈希表(可以理解为创建哈希表的对象)。

    语法如下:

    Result = Hash( Key1, Value1, Key2, Value2, ... KEYN, Valuen, /EXTRACT, /FOLD_CASE, /NO_COPY )

    Result = Hash( Keys, Values, /EXTRACT, /FOLD_CASE )

    Result = Hash( Keys , /FOLD_CASE )

    Result = Hash( Structure, /EXTRACT, /FOLD_CASE, /LOWERCASE)

             创建一个哈希表,存放个人信息:Name、Work、Age、From,这些其实就是哈希表中的Key,其所对应的值就是Value。

    1. >>Me = Hash('Name','胡','Work','搬砖','Age',18,'From','Jiangxi')
    2. >>help,Me
    3. ME HASH <ID=1 NELEMENTS=4>
    4. >>Print,Me
    5. Age: 18
    6. Work: 搬砖
    7. Name: 胡
    8. From: Jiangxi
    9. >>Print,Me['From'] ; 查看From关键字
    10. Jiangxi

             哈希表没有Add方法,但可以使用Hash["Key"] = Value

    1. >>Me['Love'] = 'Wife'
    2. >>Print,Me['Love']
    3. Wife

    2.2 访问哈希表

         访问方法如下:

    hash['Keys'] 

    1. >> ; 该代码承接上一个代码
    2. >>Print,Me['From']
    3. Jiangxi

     注意:此处关键字是区分大小写的,如下所示。

    1. >>Print,Me['Name']
    2. >>Print,Me['name']
    3. % Key does not exist: "name"
    4. % Execution halted at: $MAIN$

    2.3 哈希表操作方法

    2.3.1 Hash::Count 统计

            该方法是统计哈希表中元素(关键字、或有个关键字所对应的元素)的个数

    Result = hash.Count( [Value] )

    1. >>Num = Me.Count()
    2. >>Num
    3. 5
    4. >>Print,N_elements(Me)
    5. 5

    2.3.2 Hash::Filter 过滤

            该方法是过滤选出满足条件的哈希表中的元素,生成新的哈希表,且不改变原有的哈希表。

    Result = hash.Filter( Function, Args )

    1. ; 本代码来自官方代码
    2. FUNCTION Myfilterfunction, value
    3. Return, value LE 3 || Min(value MOD [2:Fix(Sqrt(value))])
    4. END
    5. PRO Hash_Test
    6. ;Use your FUNCTION to Return only the prime numbers In HASH:
    7. var = Hash('A', 4, 'B', 5, 'C', 499, 'D', 1000)
    8. newvar = var.Filter('myfilterfunction')
    9. Print,newvar
    10. END

    输出结果为:

    2.3.3 Hash::HasKey 判断关键字

             该方法判断是否有一个关键字key,是则输出1,反之则为0。

    Result = hash.HasKey(Keys )

    1. >>Me = Hash('Name','','Work','搬砖','Age',18,'From','Jiangxi')
    2. >>Me
    3. {
    4. "Age": 18,
    5. "Work": "搬砖",
    6. "Name": "胡",
    7. "From": "Jiangxi"
    8. }
    9. >>Print,Me.haskey('Work')
    10. 1
    11. >>Print,Me->haskey('Work')
    12. 1
    13. >>Print,Me->haskey('A')

    2.3.4 Hash::IsEmpty 是否为空

            测试哈希表是否为空、存在。若为空则输出0,若非空,则输出1。

    Result = hash.IsEmpty( )

    1. >>Me = Hash('Name','胡','Work','搬砖','Age',18,'From','Jiangxi')
    2. >>Print, Me.Isempty() ; 存在时
    3. 0
    4. >>I = Hash()
    5. >>Print, I.Isempty() ; 空
    6. 1

    2.3.5 Hash::Keys 获取关键字key

            该方法是用来获取哈希表中的关键字key。

    Result = hash.Keys( )

    1. >>Print, Me.Keys()
    2. Age
    3. Work
    4. Name
    5. From


    2.3.6 Hash::Map 判断

            该方法是用来判断各个关键字所对应的元素是否满足要求(自定义函数、lambda),满足则

    Result = hash.Map( Function, Args )

            输出的结果是一个哈希表,其关键字与所需处理的哈希表一样,每个关键字对应的元素只能是0或1。该方法与hash::filter方法一样,不同之处在于hash::filter是筛选满足要求的哈希表关键字(及对应元素),Hash::Map方法是判断是否满足要求,满足则关键字对应的元素为1,反之则为0。

           下面是代码与2.3.2节代码一样,不同之处在于这代码使用hash::map方法。

    1. FUNCTION Myfilterfunction, value
    2. Return, value LE 3 || Min(value MOD [2:Fix(Sqrt(value))])
    3. END
    4. PRO Hash_Test
    5. ;Use your FUNCTION to Return only the prime numbers In HASH:
    6. var = Hash('A', 4, 'B', 5, 'C', 499, 'D', 1000)
    7. newvar = var.map('myfilterfunction') ; hash::map方法,判断关键字对应的元素是否满足要求
    8. Print,'newvar结果:'
    9. Print,newvar
    10. help,'newvar的类型:',newvar
    11. END

    结果显示输出的结果是一个哈希表,其关键字key和原哈希表一致:

    2.3.7 Hash::Reduce 累积

             该方法通过用户定义的函数或 Lambda 函数累积传递每个数据值,并返回单个标量结果。

    Result = hash.Reduce( Function, Args, VALUE=value)

    1. FUNCTION myreducefunction, accumvalue, value
    2. Return, accumvalue + value
    3. END
    4. PRO Hash_test
    5. ;Use your FUNCTION on a Hash OF key-value PAIRS:
    6. var = Hash('Name','胡','Work','搬砖','Age','18','From','Jiangxi')
    7. newvar = var.Reduce('myreducefunction')
    8. Print, newvar
    9. END

     注:“累积”的顺序是按照key的字母排序,而不是实际的排序。

    2.3.8 Hash::Remove 删除

     该方式是移除Hash中的元素,并可选择返回移除的值。

    Result = hash.Remove( [, Keys] [, /ALL] )

    hash.Remove [, Keys] [, /ALL]

    1. >>Me = Hash('Name','','Work','搬砖','Age','18','From','Jiangxi')
    2. >>Me.Remove,['Work','Age']
    3. >>Me
    4. {
    5. "Name": "胡",
    6. "From": "Jiangxi"
    7. }
    8. >>


    2.3.9 Hash::ToStruct 转化为结构体

            该方法是将哈希表转化为结构体。

    Result=hash.ToStruct( [, MISSING=value][, /NO_COPY] [, /RECURSIVE] [, SKIPPED=variable] )

    1. >>Me = Hash('Name','胡','Work','搬砖','Age','18','From','Jiangxi')
    2. >>I = Me.tostruct()
    3. >>help,I
    4. ** Structure <3d58e550>, 4 tags, length=64, data length=64, refs=1:
    5. AGE STRING '18'
    6. WORK STRING '搬砖'
    7. NAME STRING '胡'
    8. FROM STRING 'Jiangxi'

    2.3.10 Hash::Values 

            该方法返回一个包含哈希中所有值的 LIST。只要没有从哈希中添加或删除任何项目,hash.keys 和 hash.Values() 中的键/值对的顺序就保证保持相同。

    Result = hash.Values( )

    1. >>Me = Hash('Name','胡','Work','搬砖','Age','18','From','Jiangxi')
    2. >>list = Me.Values()
    3. >>help,list
    4. LIST LIST <ID=34 NELEMENTS=4>
    5. >>print,list
    6. 18
    7. 搬砖
    8. Jiangxi
    9. >>


    2.3.11 Hash::Where 

            该方法返回包含某个 value.hash 的所有键的 list。

    Result = hash.Where( Value [, COMPLEMENT=variable] [, COUNT=variable] [, NCOMPLEMENT=variable] )

    2.4 销毁哈希表

            可以使用Obj_destroy,Hash 来销毁哈希表

    1. >>Me = Hash('Name','','Work','搬砖','Age','18','From','Jiangxi')
    2. >>ME
    3. {
    4. "Age": "18",
    5. "Work": "搬砖",
    6. "Name": "胡",
    7. "From": "Jiangxi"
    8. }
    9. >>Obj_destroy,Me
    10. >>Me

  • 相关阅读:
    深入理解AQS之ReentrantLock源码分析
    封笔之作,阿里P8手写的Java高手是怎样练成的原理方法与实践笔记
    基于Springboot开发的家庭财务管理系统
    docker启动命令,docker重启命令,docker关闭命令
    MySQL
    如何给国产32位单片机添加SEGGER RTT 日志打印
    面试 4
    RP原型资源分享-购物类App
    模式识别——高斯分类器
    Windows系统如何部署Wing FTP Server与公网远程访问【内网穿透】
  • 原文地址:https://blog.csdn.net/weixin_41649786/article/details/126752127