[英]Finding differences in two lists
我正在考慮找到兩個列表中的差異的好方法
這是問題所在:
兩個列表有一些字符串,其中前3個數字/字符(*分隔)表示唯一鍵(后跟文本String =“key1 * key2 * key3 * text”)。
這是字符串示例:
AA1*1D*4*The quick brown fox*****CC*3456321234543~
其中“* AA1 * 1D * 4 *”是唯一鍵
List1:“index1 * index2 * index3”,“index2 * index2 * index3”,“index3 * index2 * index3”
List2:“index2 * index2 * index3”,“index1 * index2 * index3”,“index3 * index2 * index3”,“index4 * index2 * index3”
我需要匹配兩個列表中的索引並進行比較。
如果來自1個列表的所有3個索引與來自另一個列表的3個索引匹配,則我需要跟蹤新列表中的兩個字符串條目
如果一個列表中有一組索引沒有出現在另一個列表中,我需要跟蹤一側並在另一側保留一個空條目。 (上例中的#4)
返回列表
這是我到目前為止所做的,但我在這里有點掙扎:
List<String> Base = baseListCopy.Except(resultListCopy, StringComparer.InvariantCultureIgnoreCase).ToList(); //Keep unique values(keep differences in lists)
List<String> Result = resultListCopy.Except(baseListCopy, StringComparer.InvariantCultureIgnoreCase).ToList(); //Keep unique values (keep differences in lists)
List<String[]> blocksComparison = new List<String[]>(); //we container for non-matching blocks; so we could output them later
//if both reports have same amount of blocks
if ((Result.Count > 0 || Base.Count > 0) && (Result.Count == Base.Count))
{
foreach (String S in Result)
{
String[] sArr = S.Split('*');
foreach (String B in Base)
{
String[] bArr = B.Split('*');
if (sArr[0].Equals(bArr[0]) && sArr[1].Equals(bArr[1]) && sArr[2].Equals(bArr[2]) && sArr[3].Equals(bArr[3]))
{
String[] NA = new String[2]; //keep results
NA[0] = B; //[0] for base
NA[1] = S; //[1] for result
blocksComparison.Add(NA);
break;
}
}
}
}
你能為這個過程建議一個好的算法嗎?
謝謝
您可以使用HashSet。
為List1創建一個HashSet。 記住index1 * index2 * index3與index3 * index2 * index1不同。
現在迭代第二個列表。
Create Hashset for List1.
foreach(string in list2)
{
if(hashset contains string)
//Add it to the new list.
}
List one = new List();
List two = new List();
List three = new List();
HashMap<String,Integer> intersect = new HashMap<String,Integer>();
for(one: String index)
{
intersect.put(index.next,intersect.get(index.next) + 1);
}
for(two: String index)
{
if(intersect.containsKey(index.next))
{
three.add(index.next);
}
}
如果我正確理解了您的問題,您希望能夠通過“密鑰”前綴比較元素,而不是整個字符串內容。 如果是這樣,實現自定義相等比較器將允許您輕松利用LINQ集算法。
這個節目......
class EqCmp : IEqualityComparer<string> {
public bool Equals(string x, string y) {
return GetKey(x).SequenceEqual(GetKey(y));
}
public int GetHashCode(string obj) {
// Using Sum could cause OverflowException.
return GetKey(obj).Aggregate(0, (sum, subkey) => sum + subkey.GetHashCode());
}
static IEnumerable<string> GetKey(string line) {
// If we just split to 3 strings, the last one could exceed the key, so we split to 4.
// This is not the most efficient way, but is simple.
return line.Split(new[] { '*' }, 4).Take(3);
}
}
class Program {
static void Main(string[] args) {
var l1 = new List<string> {
"index1*index1*index1*some text",
"index1*index1*index2*some text ** test test test",
"index1*index2*index1*some text",
"index1*index2*index2*some text",
"index2*index1*index1*some text"
};
var l2 = new List<string> {
"index1*index1*index2*some text ** test test test",
"index2*index1*index1*some text",
"index2*index1*index2*some text"
};
var eq = new EqCmp();
Console.WriteLine("Elements that are both in l1 and l2:");
foreach (var line in l1.Intersect(l2, eq))
Console.WriteLine(line);
Console.WriteLine("\nElements that are in l1 but not in l2:");
foreach (var line in l1.Except(l2, eq))
Console.WriteLine(line);
// Etc...
}
}
...打印以下結果:
Elements that are both in l1 and l2:
index1*index1*index2*some text ** test test test
index2*index1*index1*some text
Elements that are in l1 but not in l2:
index1*index1*index1*some text
index1*index2*index1*some text
index1*index2*index2*some text
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.