Đây là thứ tôi đã ném cùng nhau một cách nhanh chóng. Nó có tham số để xác định xem có so sánh trường hợp các giá trị và khóa hay không. Ném hai chức năng này (StructEquals()
, ArrayEquals()
) vào một số loại tiện ích CFC.
Giới hạn: Không hoạt động cho cấu trúc/mảng chứa truy vấn hoặc đối tượng.
<cffunction name="StructEquals" access="public" returntype="boolean" output="false"
hint="Returns whether two structures are equal, going deep.">
<cfargument name="stc1" type="struct" required="true" hint="First struct to be compared." />
<cfargument name="stc2" type="struct" required="true" hint="Second struct to be compared." />
<cfargument name="blnCaseSensitive" type="boolean" required="false" default="false" hint="Whether or not values are compared case-sensitive." />
<cfargument name="blnCaseSensitiveKeys" type="boolean" required="false" default="false" hint="Whether or not structure keys are compared case-sensitive." />
<cfscript>
if(StructCount(stc1) != StructCount(stc2))
return false;
var arrKeys1 = StructKeyArray(stc1);
var arrKeys2 = StructKeyArray(stc2);
ArraySort(arrKeys1, 'text');
ArraySort(arrKeys2, 'text');
if(!ArrayEquals(arrKeys1, arrKeys2, blnCaseSensitiveKeys, blnCaseSensitiveKeys))
return false;
for(var i = 1; i <= ArrayLen(arrKeys1); i++) {
var strKey = arrKeys1[i];
if(IsStruct(stc1[strKey])) {
if(!IsStruct(stc2[strKey]))
return false;
if(!StructEquals(stc1[strKey], stc2[strKey], blnCaseSensitive, blnCaseSensitiveKeys))
return false;
}
else if(IsArray(stc1[strKey])) {
if(!IsArray(stc2[strKey]))
return false;
if(!ArrayEquals(stc1[strKey], stc2[strKey], blnCaseSensitive, blnCaseSensitiveKeys))
return false;
}
else if(IsSimpleValue(stc1[strKey]) && IsSimpleValue(stc2[strKey])) {
if(blnCaseSensitive) {
if(Compare(stc1[strKey], stc2[strKey]) != 0)
return false;
}
else {
if(CompareNoCase(stc1[strKey], stc2[strKey]) != 0)
return false;
}
}
else {
throw("Can only compare structures, arrays, and simple values. No queries or complex objects.");
}
}
return true;
</cfscript>
</cffunction>
<cffunction name="ArrayEquals" access="public" returntype="boolean" output="false"
hint="Returns whether two arrays are equal, including deep comparison if the arrays contain structures or sub-arrays.">
<cfargument name="arr1" type="array" required="true" hint="First struct to be compared." />
<cfargument name="arr2" type="array" required="true" hint="Second struct to be compared." />
<cfargument name="blnCaseSensitive" type="boolean" required="false" default="false" hint="Whether or not values are compared case-sensitive." />
<cfargument name="blnCaseSensitiveKeys" type="boolean" required="false" default="false" hint="Whether or not structure keys are compared case-sensitive, if array contains structures." />
<cfscript>
if(ArrayLen(arr1) != ArrayLen(arr2))
return false;
for(var i = 1; i <= ArrayLen(arr1); i++) {
if(IsStruct(arr1[i])) {
if(!IsStruct(arr2[i]))
return false;
if(!StructEquals(arr1[i], arr2[i], blnCaseSensitive, blnCaseSensitiveKeys))
return false;
}
else if(IsArray(arr1[i])) {
if(!IsArray(arr2[i]))
return false;
if(!ArrayEquals(arr1[i], arr2[i], blnCaseSensitive, blnCaseSensitiveKeys))
return false;
}
else if(IsSimpleValue(arr1[i]) && IsSimpleValue(arr2[i])) {
if(blnCaseSensitive) {
if(Compare(arr1[i], arr2[i]) != 0)
return false;
}
else {
if(CompareNoCase(arr1[i], arr2[i]) != 0)
return false;
}
}
else {
throw("Can only compare structures, arrays, and simple values. No queries or complex objects.");
}
}
return true;
</cfscript>
</cffunction>
Unit Tests cho bất cứ ai quan tâm:
public void function test_StructEquals() {
AssertTrue(utils.StructEquals({}, StructNew()));
AssertTrue(utils.StructEquals({}, StructNew(), true, true));
AssertFalse(utils.StructEquals({}, {"a": "b", "c": "d"}));
AssertTrue(utils.StructEquals({"a": "b", "c": "d"}, {"C": "D", "A": "B"}));
AssertFalse(utils.StructEquals({"a": "b", "c": "d"}, {"C": "D", "A": "B"}, true, false));
AssertFalse(utils.StructEquals({"a": "b", "c": "d"}, {"C": "D", "A": "B"}, false, true));
AssertTrue(utils.StructEquals({"a": "b", "c": "d"}, {"C": "d", "A": "b"}));
AssertTrue(utils.StructEquals({"a": "b", "c": "d"}, {"C": "d", "A": "b"}, true, false));
AssertFalse(utils.StructEquals({"a": "b", "c": "d"}, {"C": "d", "A": "b"}, false, true));
AssertTrue(utils.StructEquals({"a": "b", "c": "d"}, {"c": "D", "a": "B"}));
AssertFalse(utils.StructEquals({"a": "b", "c": "d"}, {"c": "D", "a": "B"}, true, false));
AssertTrue(utils.StructEquals({"a": "b", "c": "d"}, {"c": "D", "a": "B"}, false, true));
var stc1 = {
"test": {
"hello": "world",
"goodbye": "space",
"somearr": [
{ "a": 1, "b": 2 },
"WORD",
[
{ "x": 97, "y": 98, "z": 99 },
{ "i": 50, "j": 51, "k": 52 }
]
]
}
};
var stc2 = {
"test": {
"goodbye": "space",
"hello": "world",
"somearr": [
{ "a": 1, "b": 2 },
"WORD",
[
{ "z": 99, "x": 97, "y": 98 },
{ "i": 50, "k": 52, "j": 51 }
]
]
}
};
AssertTrue(utils.StructEquals(stc1, stc2, true, true));
stc2.test.somearr[2] = "WOrD";
AssertTrue(utils.StructEquals(stc1, stc2));
AssertTrue(utils.StructEquals(stc1, stc2, false, true));
AssertFalse(utils.StructEquals(stc1, stc2, true, false));
stc2.test.somearr[3][1] = { "z": 99, "X": 97, "y": 98 };
AssertTrue(utils.StructEquals(stc1, stc2));
AssertFalse(utils.StructEquals(stc1, stc2, false, true));
AssertFalse(utils.StructEquals(stc1, stc2, true, false));
stc2.test.somearr[2] = "WORD";
AssertTrue(utils.StructEquals(stc1, stc2));
AssertFalse(utils.StructEquals(stc1, stc2, false, true));
AssertTrue(utils.StructEquals(stc1, stc2, true, false));
}
public void function test_ArrayEquals() {
AssertTrue(utils.ArrayEquals([], ArrayNew(1)));
AssertTrue(utils.ArrayEquals([], ArrayNew(1), true, true));
AssertFalse(utils.ArrayEquals([], [1, 2, 3]));
AssertTrue(utils.ArrayEquals(['a', 'b', 'c'], ['A', 'B', 'C']));
AssertFalse(utils.ArrayEquals(['a', 'b', 'c'], ['A', 'B', 'C'], true, false));
AssertTrue(utils.ArrayEquals(['a', 'b', 'c'], ['A', 'B', 'C'], false, true));
AssertFalse(utils.ArrayEquals(['a', 'b', 'c'], ['a', 'c', 'b']));
AssertTrue(utils.ArrayEquals([1, 2, 3], [1, 2, 3]));
AssertFalse(utils.ArrayEquals([1, 2, 3], [1, 3, 2]));
}
hmm .. typo? 'nguyên nhân' id số 70634 "và" idnumber 70634 "không giống nhau – Henry
có thực sự là lỗi đánh máy! –