26
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}
```