我正在努力训练在Actionscript-3中匹配两个词典的最快方法。这就是我到目前为止所做的。
function compareDictionaries(p0:Dictionary, p1:Dictionary):Boolean
{
if(p0 == p1) {
return true;
} else {
const matched:Dictionary = new Dictionary();
for(var k0:Object in p0) {
matched[k0] = k0;
if(p0[k0] != p1[k0]) {
return false;
}
}
for(var k1:Object in p1) {
if(matched[k1]) {
continue;
} else {
if(p1[k1] != p0[k1]) {
return false;
}
}
}
return true;
}
}
显然,使用项目的键创建一个新词典并不理想,但我真的不想重新测试匹配的项目(不知道这是否更慢或者没有!)。这当然可以通过在字典类上设置一个长度来避开,这将使第二个for循环冗余。
对此更好的想法?
修改
我创建了gist基准来显示成功匹配的结果(使用发布播放器)
(结果输出(ms)) 真正 43 真正 497 真正 22 真正 16
编辑2 我创造了另一个gist,显示了平等的错失。
(结果输出(ms)) 假 1 假 472 假 0 假 0
答案 0 :(得分:1)
首先比较严格的平等。然后,测试两个词典中键的相等性:
只有通过所有这些测试,才能比较实际值:
public function areEqualDictionaries( dict1:Dictionary, dict2:Dictionary ):Boolean {
if(dict1 === dict2) return true;
var keys:Array = equalKeysArrayOrNull( dict1, dict2 );
if(keys)
return haveEqualValues( keys, dict1, dict2 );
else
return false;
}
private function equalKeysArrayOrNull( dict1:Dictionary, dict2:Dictionary ):Array {
var keys1:Array = enumerateKeys( dict1 ).sort();
var keys2:Array = enumerateKeys( dict2 ).sort();
if( keys1.length != keys2.length ) return null;
var i:int = -1;
while(++i < keys1.length)
if(keys1[i] !== keys2[i]) return null;
return keys1;
}
private function haveEqualValues ( keys:Array, dict1 : Dictionary, dict2:Dictionary) :Boolean {
for each (var key:* in keys)
if (dict1[key] != dict2[key]) return false;
return true;
}
private function enumerateKeys( dict:Dictionary ):Array {
var keys:Array = [];
for(var key:* in dict)
keys.push( key );
return keys;
}
请注意,字典使用identity(严格相等)来匹配键,这使得必须使用!==
来比较它们。我想可以使用!=
来比较这些值。
这是我自己的基准for
与for each
:
var dict : Dictionary = new Dictionary();
var keys : Array = [];
for (var i : int = 0; i < 1000000; i++) {
var n : Object = { index:i };
dict[n] = n;
keys.push (n);
}
trace ("benchmark:");
trace ("----------");
var start : int = getTimer();
for each (var key:* in keys) {
var m:* = dict[key];
}
var elapsed : int = getTimer() - start;
trace ("for each:" + elapsed);
trace ("----------");
start = getTimer();
for (var j:int = 0; j < keys.length; j++) {
var o:* = dict[keys[j]];
}
elapsed = getTimer() - start;
trace ("for:" + elapsed);
在我的机器上返回:
for each:213
----------
for:274
答案 1 :(得分:1)
像这样简单的东西应该有用 - 没有新的数组/字典等:
public function compareDictionaries( d1:Dictionary, d2:Dictionary ):Boolean
{
// quick check for the same object
if( d1 == d2 )
return true;
// check for null
if( d1 == null || d2 == null )
return false;
// go through the keys in d1 and check if they're in d2 - also keep a count
var count:int = 0;
for( var key:* in d1 )
{
// check if the key exists
if( !( key in d2 ) )
return false;
// check that the values are the same
if( d1[key] != d2[key] )
return false;
count++;
}
// now just make sure d2 has the same number of keys
var count2:int = 0;
for( key in d2 )
count2++;
// return if they're the same size
return ( count == count2 );
}
从技术上讲,您可以直接与值进行比较(如不检查d2中是否存在密钥),就好像您搜索不存在的密钥一样,它应该解析为null
(或undefined
,我不是百分百肯定的),但如果d1
中的值为空且d2
<中不存在,我将其留在那里/ p>