25
2019.2

Dictionary函数

作者: POPASP
POP_MVC.Dict的处理函数,主要有五大类:修改、过滤、查找、数组函数、集合函数、排序、其他 ## 修改函数 修改函数直接修改传入的数组,这点须注意。 ### Push 函数 在数组中也有Push方法,它有两个参数,一个是数组,一个插入值。向Dictionary对象(以下在不引起混淆的情况下,简称为对象)插入键值对时,须传入三个参数,一个是对象,一个是键名,另外一个是插入值。 **功能** 向Dictionary对象尾部添加一个键值对 **参数说明** Sub Push(ByRef dict, ByRef key, ByRef val) dict 参数,待操作对象,如果dict不是Dictionary对象,则将其转化为对象 key 参数,键名 val 参数,插入值 如果插入的键名在对象中已经存在,则首先删除它,再向尾部插入。 **返回值** 无返回值,直接将元素添加到对象上 **举例** ```brush:vb dim dict POP_MVC.Dict.Push dict,"a","aa" POP_MVC.Dict.Push dict,"b","bb" POP_MVC.Dict.Push dict,"c","cc" POP_MVC.Dict.Push dict,"b","dd" var_export dict '{"a":"aa", "c":"cc", "b":"dd"} ``` ### Unshift 函数 **功能** 向Dictionary对象头部添加一个键值对 **参数说明** Sub Push(ByRef dict, ByRef key, ByRef val) dict 参数,待操作对象,如果dict不是Dictionary对象,则将其转化为对象 key 参数,键名 val 参数,插入值 **返回值** 无返回值,直接将元素添加到对象上 如果插入的键名在对象中已经存在,则首先删除它,再向头部插入。 **举例** ```brush:vb dim dict POP_MVC.Dict.Unshift dict,"a","aa" POP_MVC.Dict.Unshift dict,"b","bb" POP_MVC.Dict.Unshift dict,"c","cc" POP_MVC.Dict.Unshift dict,"b","dd" var_export dict '{"b":"bb", "c":"cc", "a":"aa"} ``` ### InsertBefore 函数 **功能** 向Dictionary对象的某个键名前面插入一个键值对 **参数说明** Sub InsertBefore( ByRef dict, ByRef beforeKey, ByRef key,ByRef val) dict 参数,待操作对象,如果dict不是Dictionary对象,则将其转化为对象 beforeKey 参数,在该键名之前插入键值对 key 参数,键名 val 参数,插入值 **返回值** 无返回值,直接将元素添加到对象上 如果向不存在的键名前面插入键值对,则会追加到对象尾部 如果要插入的键值对其键名已经存在于对象中,则首先从对象中将移除原键值对 **举例** ```brush:vb dim dict POP_MVC.Dict.Unshift dict,"a","aa" '{"a":"aa"} POP_MVC.Dict.InsertBefore dict,"a","b","bb" '{"b":"bb", "a":"aa"} POP_MVC.Dict.InsertBefore dict,"a","c","cc" '{"b":"bb", "c":"cc", "a":"aa"} POP_MVC.Dict.InsertBefore dict,"c","b","bb2" '{"b":"bb2", "c":"cc", "a":"aa"} ``` ### InsertAfter 函数 **功能** 向Dictionary对象的某个键名后面插入一个键值对 **参数说明** Sub InsertAfter( ByRef dict, ByRef afterKey, ByRef key,ByRef val) dict 参数,待操作对象,如果dict不是Dictionary对象,则将其转化为对象 afterKey 参数,在该键名之后插入键值对 key 参数,键名 val 参数,插入值 **返回值** 无返回值,直接将元素添加到对象上 如果向不存在的键名前面插入键值对,则会追加到对象尾部 如果要插入的键值对其键名已经存在于对象中,则首先从对象中将移除原键值对 **举例** ```brush:vb dim dict POP_MVC.Dict.Unshift dict,"a","aa" '{"a":"aa"} POP_MVC.Dict.InsertAfter dict,"a","b","bb" '{"a":"aa", "b":"bb"} POP_MVC.Dict.InsertAfter dict,"a","c","cc" '{"a":"aa", "c":"cc", "b":"bb"} POP_MVC.Dict.InsertAfter dict,"a","b","bb2" '{"a":"aa", "b":"bb2", "c":"cc"} ``` 上面四个函数,Push、Unshift、InsertBefore、InsertAfter都是向对象中添加元素,除了这四个函数外,原生的Dictionary.Add方法也可以向数组尾部添加元素,但是添加的键如果已经存在于对象中,则会出错,所以建议使用POPASP的方法向对象尾部添加元素。 在处理数组时,POPASP提供了POP_MVC.Array.Insert方法,该方法是向指定位置前面插入元素,因为数组的下标是一个连贯的非负整数集,所以没有必要细分InsertBefore与InsertAfter,而对于Dictionary对象则不同,它的键名非连贯,在指定插入位置时,则不得不区分是向前插入还是向后插入。 有插入就有删除,删除对象元素的函数有原生的Dictionary.Remove方法,另外POPASP还提供了两个方法 ### Pop 函数 **功能** 从Dictionary对象中删除最后一个键值对,并以数组形式返回 **参数说明** Function Pop(ByRef dict) dict 参数,待操作对象 **返回值** 返回被删除的元素。如果dict不是Dictionary对象,返回值为Empty,如果对象不含任何元素,返回值也为Empty。正常情况下返回一个数组,数组的第一个元素为键 名,第二个元素为值,即 Array(key,val) 的形式。 **举例** ```brush:vb dim dict,arr POP_MVC.Dict.Push dict,"a","aa" '{"a":"aa"} POP_MVC.Dict.Push dict,"b","bb" '{"a":"aa", "b":"bb"} POP_MVC.Dict.Push dict,"c","cc" '{"a":"aa", "b":"bb","c":"cc"} '将最后一个元素删除后,dict为{"a":"aa", "b":"bb"} 'arr 为["c", "cc"],可以看出arr(0)为原键名,arr(1)为原值 arr = POP_MVC.Dict.Pop(dict) ``` ### Shift 函数 **功能** 从Dictionary对象中删除第一个键值对,并以数组形式返回 **参数说明** Function Shift(ByRef dict) dict 参数,待操作对象 **返回值** 返回被删除的元素。如果dict不是Dictionary对象,返回值为Empty,如果对象不含任何元素,返回值也为Empty。正常情况下返回一个数组,数组的第一个元素为键 名,第二个元素为值,即 Array(key,val) 的形式。 **举例** ```brush:vb dim dict,arr POP_MVC.Dict.Push dict,"a","aa" '{"a":"aa"} POP_MVC.Dict.Push dict,"b","bb" '{"a":"aa", "b":"bb"} POP_MVC.Dict.Push dict,"c","cc" '{"a":"aa", "b":"bb","c":"cc"} '将最后一个元素删除后,dict为{"b":"bb", "c":"cc"} 'arr 为["a", "aa"],可以看出arr(0)为原键名,arr(1)为原值 arr = POP_MVC.Dict.Shift(dict) ``` 因为ASP提供了现成的Dictionary.Remove与Dictionary.RemoveAll两个方法,而且使用使用也非常简便,所以POPASP就没有再提供Remove方法。 除了上面的给数组增加或者删除元素的数组外,还有其他几个函数,也涉及到了修改对象。 ### vswap 函数 **功能** 将Dictionary对象两个键名对应的值进行交换 **参数说明** Sub vswap( byref dict,byval key1,byval key2 ) dict 参数,待操作对象 key1 参数,第一个指定的键名 key2 参数,第二个指定的键名 两个键名同时存在时才进行交换,而且只是值交换,键名并不交换。 **返回值** 无返回值,直接在对象上进行修改 **举例** ```brush:vb dim dict POP_MVC.Dict.Push dict,"a","aa" '{"a":"aa"} POP_MVC.Dict.Push dict,"b","bb" '{"a":"aa", "b":"bb"} POP_MVC.Dict.Push dict,"c","cc" '{"a":"aa", "b":"bb","c":"cc"} POP_MVC.Dict.vswap dict,"a","c" '{"a":"cc", "b":"bb", "c":"aa"} ``` ### kswap 函数 **功能** 将Dictionary对象两个键名进行交换 **参数说明** Sub kswap( ByRef dict,ByVal key1,ByVal key2 ) dict 参数,待操作对象 key1 参数,第一个指定的键名 key2 参数,第二个指定的键名 两个键名同时存在时才进行交换,而且只是键名交换,值并不交换。 **返回值** 无返回值,直接在对象上进行修改 **举例** ```brush:vb dim dict POP_MVC.Dict.Push dict,"a","aa" '{"a":"aa"} POP_MVC.Dict.Push dict,"b","bb" '{"a":"aa", "b":"bb"} POP_MVC.Dict.Push dict,"c","cc" '{"a":"aa", "b":"bb","c":"cc"} POP_MVC.Dict.kswap dict,"a","c" '{"c":"aa", "b":"bb", "a":"cc"} ``` ### kvswap 函数 **功能** 将Dictionary对象的两个键值对进行交换,相当于两个键值对交换了位置 **参数说明** Sub kvswap( ByRef dict,ByVal key1,ByVal key2 ) dict 参数,待操作对象 key1 参数,第一个指定的键名 key2 参数,第二个指定的键名 **返回值** 无返回值,直接在对象上进行修改 **举例** ```brush:vb dim dict POP_MVC.Dict.Push dict,"a","aa" '{"a":"aa"} POP_MVC.Dict.Push dict,"b","bb" '{"a":"aa", "b":"bb"} POP_MVC.Dict.Push dict,"c","cc" '{"a":"aa", "b":"bb","c":"cc"} POP_MVC.Dict.kvswap dict,"a","c" '{"c":"cc", "b":"bb", "a":"aa"} ``` ### Edit 函数 **功能** 修改一对键值对,如果存在则修改,否则向尾部添加 **参数说明** Sub Edit(ByRef dict,ByVal key, ByRef val) dict 参数,待操作对象,如果dict不是Dictionary对象,则将其转化为对象 key 参数,键名 val 参数,值 如果键名存在则修改,否则向尾部添加。该方法与Push不同,如果存在键名,Edit会在该键名处修改值,而Push会删除该键,而向对象添加。 **返回值** 无返回值,直接作用于对象 **举例** ```brush:vb dim dict POP_MVC.Dict.Push dict,"a","aa" '{"a":"aa"} POP_MVC.Dict.Push dict,"b","bb" '{"a":"aa", "b":"bb"} POP_MVC.Dict.Push dict,"c","cc" '{"a":"aa", "b":"bb","c":"cc"} POP_MVC.Dict.Edit dict,"b","bb2" '{"a":"aa", "b":"bb2", "c":"cc"} POP_MVC.Dict.Push dict,"a","aa2" '{"b":"bb2", "c":"cc", "a":"aa2"} ``` ## 过滤函数 取片段函数有一个:Filter。函数不会直接修改原对象,而是返回一个新对象。 ### Filter 函数 **功能** 用回调函数过滤对象中的单元 **参数说明** `Function [Filter]( Byref dict, Byref callback )` dict 参数,待操作数组 callback 参数,回调函数 依次将 dict 数组中的每个键值对传递到 callback 函数。如果 callback 函数返回 TRUE,则 dict 数组的当前值会被包含在返回的结果对象中。 **返回值** 返回符合过滤条件的新对象,如果没有符合条件的键值对时,返回空对象。 **举例** ```brush:vb '定义过滤函数,过滤函数必须含有两个参数,第一个对应键名,第二个对应值 Function includeFunc( key,item ) if POP_MVC.String.Exists(item,"过滤") Then includeFunc = true else includeFunc = false end if End Function ``` ```brush:vb dim dict,ret set dict = POP_MVC.Dict.Create() dict.Add "a","过滤AA" dict.Add "b","BB" dict.Add "c","过滤CC" dict.Add "d","DD" '{"a":"过滤AA", "b":"BB", "c":"过滤CC", "d":"DD"} '因为返回值是对象,所以必须用set来接收返回值,当然过滤后有可能是个空对象 set ret = POP_MVC.Dict.Filter(dict,"includeFunc") '{"a":"过滤AA", "c":"过滤CC"} ``` POP_MVC.Dict.Filter与POP_MVC.Array.Filter功能很相似,只是前者用来过滤对象,后者用来过滤数组,返回的值前者得到的是对象,后者得到的是数组。 ## 查找函数 POPASP针对Dictionary对象提供了两个方法来进行查找,不过,使用更多的应该数原生的Dictionary.Exists方法,它原来查找一个键是否存在。 ### Exists 函数 **功能** 判断某个值是否存在于对象中,返回True或者False **参数说明** Function Exists( ByRef dict, ByRef val ) arr 参数,待查找数组 val 参数,待查找的值,只能是标量,或者可以通过=来判断相等的对象 **返回值** 存在返回True,不存在返回False **举例** ```brush:vb dim arr,dict,ret arr = array(1,2,3,"a","b","c") '通过数组快速创建一个Dictionary对象 set dict = POP_MVC.Arr.toDict(arr) '{"0":1, "1":2, "2":3, "3":"a", "4":"b", "5":"c"} '通过POP_MVC.Dict.Exists来查找值是否存在 ret = POP_MVC.Dict.Exists( dict,"a" ) 'True '通过Dictionary.Exists来查找键是否存在 ret = dict.Exists("3") 'True ``` ### Search 函数 **功能** 在对象中搜索给定的值,如果成功则返回相应的键名,否则返回Empty(数组中也有同名函数,找不到时返回的是-1) **参数说明** Function Search( ByRef dict, ByRef val ) dict 参数,待查找对象 val 参数,待查找的值,只能是标量,或者可以通过=来判断相等的对象 **返回值** 存在返回键名,不存在返回Empty **举例** ```brush:vb dim arr,dict,ret arr = array(1,2,3,"a","b","c") '通过数组快速创建一个Dictionary对象 set dict = POP_MVC.Arr.toDict(arr) '{"0":1, "1":2, "2":3, "3":"a", "4":"b", "5":"c"} ret = POP_MVC.Dict.Search( dict,"a" ) '"3" ``` ## 数组函数 Dictionary对象在某些方面可以看成是数组,原生的两个方法Dictionary.keys与Dictionary.items,也分别是将键名与值分别抽出为一个数组。尤其是值集,很多时候需要将其当数组来处理,为了使用方便,POPASP特在POPASP_DICTIONARY类中集成了三个方法,分别是Unique、Produce、Product。并通过源码分析,来剖析其实现原理,以达到在实际工作中灵活使用的目的。 ### Unique 函数 Unique函数的本质是将对象当成数组,进行唯一值的过滤。如果对象中的元素有过于复杂的对象类型,则不能使用该函数,否则会出错。Unqiue函数,返回值是数组,而非对象,这是因为如果有重复值的话,保留键名就毫无意义。 **功能** 移除对象中重复的值并将剩余的值返回一个数组 **参数说明** Function Unique( ByRef dict ) dict 参数,待操作对象 **返回值** 返回一个数组 **源码分析** ```brush:vb Function Unique( ByRef dict ) Unique = POP_MVC.Arr.Unique( dict.Items ) End Function ``` 从源码中可以看出来,使用了数组的Unique函数,作用对象实质上是对象的值的集合。 **举例** ```brush:vb dim dict,arr POP_MVC.Dict.Push dict,"a","aa" '{"a":"aa"} POP_MVC.Dict.Push dict,"b","bb" '{"a":"aa", "b":"bb"} POP_MVC.Dict.Push dict,"aa","aa" '{"a":"aa", "b":"bb","aa":"aa"} POP_MVC.Dict.Push dict,"bb","bb" '{"a":"aa", "b":"bb","aa":"aa", "bb":"bb"} arr = POP_MVC.Dict.Unique(dict) '["aa", "bb"] ``` Reduce与Product在数组中对应的是迭代函数,迭代函数会将每一次迭代得到的结果会作为下一次迭代的初始值,不断逼近所需要的结果。 ### Product 函数 **功能** 计算对象中所有值的乘积 **参数说明** Function Product( ByRef dict ) dict 参数,待迭代对象 **返回值** 返回一个数值 **举例** ```brush:vb dim arr,ret,dict arr = array(1,2,3,"a","b","c",4,5) set dict = POP_MVC.Arr.toDict(arr) '将数组中的数值元素1、2、3、4、5进行相乘 ret = POP_MVC.Dict.Product(dict) ' 120 ``` Product函数只是简单的将数组中的数值迭代相乘。而这并不能满足个性个需求,如果需要个性化定制,请使用Reduce ### Reduce 函数 **功能** 用回调函数迭代地将对象的值集简化为单一的值 **参数说明** Function Reduce( ByRef dict,ByRef func,ByRef initial ) dict 参数,待迭代对象 func 参数,迭代函数的函数名 initial 参数,初始值 **返回值** 返回一个数值或字符串 **举例** ```brush:vb '数组的迭代函数与对象的迭代函数并没有什么不同 Function reduceFunc( a,b ) if isNumeric(a) and isNumeric(b) then reduceFunc = a + b * b elseif isNumeric(a) then reduceFunc = a * a elseif isNumeric(b) then reduceFunc = b * b end if End Function ``` ```brush:vb '使用迭代函数 dim arr,ret,dict arr = array("a","b","c",1,2,3) set dict = POP_MVC.Arr.toDict(arr) 'ret = 1 + 1*1 + 2*2 + 3*3 ret = POP_MVC.Dict.Reduce(dict,"reduceFunc",1) ' 15 '不要初始值 'ret = 1*1 + 2*2 + 3*3 ret = POP_MVC.Dict.Reduce(dict,"reduceFunc",null) ' 14 ``` 类似于数组中的join方法,POPASP在对象中也提供了两个方法,ItemJoin与KeyJoin,前者是将值联接成一个字符串,后者是将键名连接成一个字符串。 ### KeyJoin 函数 **功能** 将键名联接起来 **参数说明** Function KeyJoin( ByRef args ) args 参数,可以为Dictionary对象,也可以为数组 如果只提供一个参数,则该参数应为Dictionary对象,默认分隔符为空字符"" 如果参数为数组,则第一个参数为Dictionary对象,第二个参数为delimiter **返回值** 返回一个字符串 **举例** ```brush:vb dim dict,str1,str2 set dict = D_ dict("name") = "张三" dict("sex") = "男" dict("age") = 24 str1 = POP_MVC.Dict.KeyJoin(dict) '"namesexage" str2 = POP_MVC.Dict.KeyJoin( array(dict,"-") ) '"name-sex-age" ``` ### ItemJoin 函数 **功能** 将值联接起来 **参数说明** Function ItemJoin( ByRef args ) args 参数,可以为Dictionary对象,也可以为数组 如果只提供一个参数,则该参数应为Dictionary对象,默认分隔符为空字符"" 如果参数为数组,则第一个参数为Dictionary对象,第二个参数为delimiter **返回值** 返回一个字符串 **举例** ```brush:vb dim dict,str1,str2 set dict = D_ dict("name") = "张三" dict("sex") = "男" dict("age") = 24 str1 = POP_MVC.Dict.ItemJoin(dict) '"张三男24" str2 = POP_MVC.Dict.ItemJoin( array(dict,"--") ) '"张三--男--24" ``` ## 集合函数 POPASP提供了三个集合函数,Merge、Diff、Intersect,分别表示求并集、差集、交集。这三个集合函数比较的都是键名。 ### Merge 函数 **功能** 合并两个对象 如果两个对象中同时存在某键,后者覆盖前者 **参数说明** Function Merge( ByRef dict1,ByRef dict2 ) dict1 参数,待操作对象一 dict2 参数,待操作对象二 **返回值** 返回合并后的对象 **举例** ```brush:vb dim dict1,dict2,dict,temp set dict1 = D_ dict1("name") = "张三" dict1("sex") = "男" dict1("age") = 24 set dict2 = D_ dict2("name") = "李四" dict2("age") = 22 dict2("favorite") = "篮球" set dict = POP_MVC.Dict.Diff(dict1,dict2) '{"sex":"男"} set temp = POP_MVC.Dict.Diff(dict2,dict1) '{"favorite":"篮球"} ``` ### Diff 函数 **功能** 计算对象的差集 **参数说明** Function Diff ( ByRef dict1,ByRef dict2 ) dict1 参数,待操作对象一 dict2 参数,待操作对象二 **返回值** 类似于PHP中的 array_diff_key,返回一个对象,该对象包括了所有在 dict1 中但是不在 dict2 中键名的值。注意比较的是键名。 **举例** ```brush:vb dim dict1,dict2,dict,temp set dict1 = D_ dict1("name") = "张三" dict1("sex") = "男" dict1("age") = 24 set dict2 = D_ dict2("name") = "李四" dict2("age") = 22 dict2("favorite") = "篮球" set dict = POP_MVC.Dict.Diff(dict1,dict2) '{"sex":"男"} set temp = POP_MVC.Dict.Diff(dict2,dict1) '{"favorite":"篮球"} ``` ### Intersect 函数 **功能** 计算对象的交集 **参数说明** Function Diff ( ByRef dict1,ByRef dict2 ) dict1 参数,待操作对象一 dict2 参数,待操作对象二 **返回值** 类似于PHP中的 array_intersect_key,返回一个对象,该对象包括了所有在 dict1 中同时存在于 dict2 中键名的值。注意比较的是键名。 **举例** ```brush:vb dim dict1,dict2,dict,temp set dict1 = D_ dict1("name") = "张三" dict1("sex") = "男" dict1("age") = 24 set dict2 = D_ dict2("name") = "李四" dict2("age") = 22 dict2("favorite") = "篮球" set dict = POP_MVC.Dict.Intersect(dict1,dict2) '{"name":"张三", "age":24} set temp = POP_MVC.Dict.Intersect(dict2,dict1) '{"name":"李四", "age":22} ``` Merge函数是“后来者居上”,而Diff与Intersect函数是都是“先入为主”,区分一定要搞清楚。 ## 排序函数 POPASP提供了丰富的排序函数,不仅可以对值进行排序,而且可以对键名进行排序。对象的排序函数跟数组的排序函数很相似,但是对象的排序多了一组对键名的排序函数。为了说明问题,我们以表格的形式先列出来。 | 排序函数 | 采用的比较方法 | 功能 | | -------- | ----- | ---- | | sort | POP_MVC.String.cmp | 按照字符串值正向排序 | | rsort | POP_MVC.String.cmp | 按照字符串值逆向排序 | | ksort | POP_MVC.String.cmp | 按照键名正向排序 | | krsort | POP_MVC.String.cmp | 按照键名逆向排序 | | casesort | POP_MVC.String.casecmp | 按照字符串值正向排序,并且忽略大小写 | | casersort | POP_MVC.String.casecmp | 按照字符串值逆向排序,并且忽略大小写 | | caseksort | POP_MVC.String.casecmp | 按照键名正向排序,并且忽略大小写 | | casekrsort | POP_MVC.String.casecmp | 按照键名逆向排序,并且忽略大小写 | | natsort | POP_MVC.String.natcmp | 用“自然排序”算法按照字符串值正向排序 | | natrsort | POP_MVC.String.natcmp | 用“自然排序”算法按照字符串值逆向排序 | | natksort | POP_MVC.String.natcmp | 用“自然排序”算法按照键名正向排序 | | natkrsort | POP_MVC.String.natcmp | 用“自然排序”算法按照字符串值逆向排序 | | casenatsort | POP_MVC.String.casenatcmp | 用“自然排序”算法按照字符串值正向排序 ,并且忽略大小写 | | casenatrsort | POP_MVC.String.casenatcmp | 用“自然排序”算法按照字符串值逆向排序 ,并且忽略大小写 | | casenatksort | POP_MVC.String.casenatcmp | “自然排序”算法按照键名正向排序 ,并且忽略大小写 | | casenatkrsort | POP_MVC.String.casenatcmp | 用“自然排序”算法按照键名逆向排序 ,并且忽略大小写 | 排序函数虽然很多,但有一定的规律,按照规律来理解使用,可以事半功倍。 ### sort 函数 **功能** 按照字符串值正向排序 **参数说明** sub sort( ByRef dict ) dict 参数,待排序对象 如果两个比较元素同为日期型,则最新的日期值>较早的日期值 如果两个比较元素同为数值型,则比较数值大小 其他值的比较按字符串比较,使用了POP_MVC.String.cmp进行比较 **返回值** 无返回值,直接在传入的对象参数上进行排序 **举例** ```brush:vb dim arr,dict arr = array("a","b","c",1,2,3,"2016-3-1",#2015-4-2#) '将数组转化为对象 set dict = POP_MVC.Arr.toDict(arr) '{"3":1, "4":2, "7":"2015\/4\/2", "6":"2016-3-1", "5":3, "0":"a", "1":"b", "2":"c"} call POP_MVC.Dict.sort(dict) ``` 通过sort函数,可以发现,这组排序函数,都只有一个参数,即待排序的Dictionary对象,都为sub过程,没有返回值。排序操作直接作用在传入的对象身上。为了说明问题,我们再来看一个。 ### natsort 函数 **功能** 用“自然排序”算法按照字符串值正向排序 **参数说明** Sub natrsort( ByRef dict ) dict 参数,待排序对象 如果两个比较元素同为日期型,则最新的日期值>较早的日期值 如果两个比较元素同为数值型,则比较数值大小 其他值的比较按字符串比较,使用了 POP_MVC.String.natcmp 进行比较 **返回值** 无返回值,直接在传入的对象参数上进行排序 **举例** ```brush:vb dim arr,dict 'arr数组中有一些文件名 arr = array("image1.jpg","image5.jpg","image10.jpg","image30.jpg") '为了演示需要,我们将数组转化成对象 set dict = POP_MVC.Arr.toDict(arr) call POP_MVC.dict.sort(dict) '{"0":"image1.jpg", "2":"image10.jpg", "3":"image30.jpg", "1":"image5.jpg"} '使用sort函数,并不会得到我们想要的结果,须用natsort call POP_MVC.Dict.natsort(dict) '{"0":"image1.jpg", "1":"image5.jpg", "2":"image10.jpg", "3":"image30.jpg"} ``` 通过上面的例子,已经将问题说明白,没有必要将每个函数再一一做演示。 上面这么多排序函数,在程序内部,对值进行升序排序都使用了函数POP_MVC.Dict.AscSortByFunc函数,对键名进行升序排序都使用了函数AscKeySortByFunc,对值进行降序排序都使用了函数POP_MVC.Array.DescSortByFunc,对键名进行降序排序都使用了函数DescKeySortByFunc。比如,我们来看sort函数的源码 ``` Sub sort( ByRef dict ) call AscSortByFunc( dict , "POP_MVC.String.cmp") End Sub ``` 再比如,我们来看casekrsort的源码 ``` Sub casekrsort( ByRef dict ) call DescKeySortByFunc( dict , "POP_MVC.String.casecmp") End Sub ``` 在函数内部,均一行代码就实现了函数功能。这得归功于POP_MVC.Array.AscSortByFunc与POP_MVC.Array.DescKeySortByFunc函数。而这两函数,是通过私有方法sortByFunc来实现的。 ```brush:vb '按自定义函数进行升序排序, Public Sub AscSortByFunc( ByRef dict , ByRef funcComp ) call sortByFunc( dict , funcComp,false ) End Sub ``` ```brush:vb '对dict按照键名逆向排序 Public Sub DescKeySortByFunc( ByRef dict , ByRef funcComp ) call ksortByFunc( dict , funcComp,true ) End Sub ``` 这些排序函数还有一个特点,在刚才的示例中,可以看到,它们不仅可以对字符串进行排序,而且还可以对数值型、日期型元素进行排序。如果仅仅想通过字符串排序,而不想对这两种类型数据进行排序,可以使用两个属性来关闭。 ```brush:vb 'sortByDate默认值是True POP_MVC.Dict.sortByDate = Fasle 'sortByNumeric默认值是True POP_MVC.Dict.sortByNumeric = Fasle ``` 对象的排序函数在定义、使用上都与数组的排序函数十分相似。 一般来说,对象中的元素都是同一种类型,如果不同类型的数据在一起排序的意义不大,如果对象中有对象类型的数据(非日期对象),则不能进行正常排序。 上面的排序函数,基本已经满足需求。如果想进行个性化的排序,那么就要使用usort或者uksort函数。 ### usort 函数 **功能** 按用户自定义的比较函数根据值进行排序 **参数说明** Sub usort( ByRef dict,ByRef funcComp ) dict 参数,待操作对象 funcComp 参数,回调函数 本函数将用用户自定义的比较函数对一个对象中的值进行排序。如果要排序的对象需要用一种不寻常的标准进行排序,那么应该使用此函数。 比较函数必须在第一个参数被认为小于,等于或大于第二个参数时分别返回一个小于,等于或大于零的整数。 **返回值** 无返回值,直接在传入的对象参数上进行排序 **举例** ```brush:vb '定义排序函数 Function sortFunc( item ) sortFunc = DateDiff( "s", "2013-10-1" , item(2) ) End Function ``` ```brush:vb '使用 POP_MVC.Dict.usort 函数对对象中的标量进行排序自不必说 '现在来看,如何使用它对复杂对象进行排序 dim arr,ret,dict '首先创建一个二维数组 arr = array( _ array("1","a","2011-3-4") , _ array("2","b","2010-4-5") , _ array("3","c","2014-1-1") , _ array("4","d","2016-8-16") _ ) '接下来把二维数组转化成对象,每个元素仍然是一维数组 set dict = POP_MVC.Arr.toDict(arr) '{"1":[2, "b", "2010-4-5"], "0":[1, "a", "2011-3-4"], "2":[3, "c", "2014-1-1"], "3":[4, "d", "2016-8-16"]} ret = POP_MVC.Dict.usort(dict,"sortFunc") ``` ### uksort 函数 **功能** 使用用户自定义的比较函数根据键名进行排序 **参数说明** Sub uksort( ByRef dict,ByRef funcComp ) dict 参数,待操作对象 funcComp 参数,回调函数 本函数将用用户自定义的比较函数对一个对象中的键名进行排序。如果要排序的对象需要用一种不寻常的标准进行排序,那么应该使用此函数。 比较函数必须在第一个参数被认为小于,等于或大于第二个参数时分别返回一个小于,等于或大于零的整数。 **返回值** 无返回值,直接在传入的对象参数上进行排序 ## 其他函数 ### Create 函数 **功能** 创建一个空对象 **参数说明** Function Create() 无参数 **返回值** Dictionary空对象 **举例** ```brush:vb dim dict1,dict2,dict3 set dict1 = Server.CreateObject("Scripting.Dictionary") set dict2 = POP_MVC.Dict.Create set dict3 = D_ ``` 示例中的三种方法都可以创建Dictionary对象。 ### Clone 函数 **功能** 克隆一个对象 **参数说明** Function Clone( ByRef Dict ) dict 参数,待操作对象 **返回值** 返回一个新对象 **举例1** ```brush:vb ' dim dict,temp set dict = D_ dict("name") = "张三" dict("sex") = "男" dict("age") = 24 '我们希望通过set语句,复制出一个对象 set temp = dict temp("age") = 28 '但是,很快会发现,在复制出的对象上的更改,也会修改到原对象中 var_export dict '{"name":"张三", "sex":"男", "age":28} ``` **举例2** ```brush:vb dim dict,temp set dict = D_ dict("name") = "张三" dict("sex") = "男" dict("age") = 24 '使用POP_MVC.Dict.Clone函数才能达到真正克隆的目的 set temp = POP_MVC.Dict.Clone(dict) temp("age") = 28 var_export dict '{"name":"张三", "sex":"男", "age":24} ``` ### Shuffle 函数 **功能** 将对象打乱 本函数打乱(随机排列单元的顺序)一个对象 **参数说明** sub shuffle( ByRef dict ) dict 参数,待操作对象 **返回值** 无返回值,直接在传入的数组参数上进行操作 **举例** ```brush:vb dim arr,dict arr = array("a","b","c","d") set dict = POP_MVC.Arr.toDict(arr) '每次打乱后的结果都不一样 call POP_MVC.Dict.Shuffle(dict) '{"3":0, "0":1, "1":2, "2":3, "0":"a", "1":"b", "2":"c", "3":"d"}这是其中之一 ``` ### Flip 函数 **功能** 交换对象中的键和值 **参数说明** Function Flip( ByRef dict ) dict 参数,待操作对象 **返回值** 返回一个新对象 **举例** ```brush:vb dim dict,temp set dict = D_ dict("name") = "张三" dict("sex") = "男" dict("age") = 24 'dict对象为 {"name":"张三", "sex":"男", "age":24} set temp = POP_MVC.Dict.Flip(dict) '{"张三":"name", "男":"sex", "24":"age"} ``` ### Combine 函数 **功能** 创建一个新对象,用一个数组的值作为其键名,另一个数组的值作为其值 **参数说明** Function Combine( ByRef keys,ByRef items ) keys 参数,数组,将要作为对象的键名 items 参数,数组,将要作为对象的值 **返回值** 返回一个对象 **举例** ```brush:vb dim dict,keys,items,temp set dict = D_ dict("name") = "张三" dict("sex") = "男" dict("age") = 24 'dict对象为 {"name":"张三", "sex":"男", "age":24} keys = dict.keys items = dict.items set temp = POP_MVC.Dict.Combine(keys,items) '{"name":"张三", "sex":"男", "age":24} ``` ### Map 函数 **功能** 将回调函数作用到给定对象的单元上,并返回一个新对象,键名保留不变 **参数说明** Function Map( ByRef dict,ByRef mapFunc ) dict 参数,待操作对象 callback 参数,回调函数 **返回值** 返回一个新对象 **举例** ```brush:vb '定义回调函数 Function mapFunc(item) mapFunc = item & "-" & item End Function ``` ```brush:vb dim dict,temp set dict = D_ dict("name") = "张三" dict("sex") = "男" dict("age") = 24 set temp = POP_MVC.Dict.Map(dict,"mapFunc") '{"name":"张三-张三", "sex":"男-男", "age":"24-24"} ``` ### Reverse 函数 **功能** 返回一个单元顺序相反的对象 **参数说明** Function Reverse ( ByRef dict ) dict 参数,待操作对象 **返回值** 返回一个单元顺序相反的对象 **举例** ```brush:vb dim dict,temp set dict = D_ dict("name") = "张三" dict("sex") = "男" dict("age") = 24 set temp = POP_MVC.Dict.Reverse(dict) '{"age":24, "sex":"男", "name":"张三"} 'dict单元顺序并不会变,仍旧为 {"name":"张三", "sex":"男", "age":24} ```