2015-04-15 2 views
0

Я пытаюсь найти эффективный способ сопоставления строк в этом словаре на основе правил, указанных в файле XML.Соответствие строковых значений в словаре на основе частичного ключа в том же словаре на основе правил, указанных в файле XML

Я попытаюсь объяснить код с самого начала. Есть два файла csv.

File1.csv

RefID|Firstname|Lastname|ID|DOB 
Ref_1|KEN|CARPENTER|67814|1122 
Ref_2|TRAY|ROBINSON|67814|1122 
Ref_3|TRAY|ROBINSON|67871|1122 
Ref_4|TRAN|ROBINSON|67871|1122 
Ref_5|LAWSN|PERDUE|6761|2009 
Ref_6|MCKEN|BARNUM|6761|2009 
Ref_7|MCKEN|BARNUM|6768|2009 
Ref_8|MCKEN|BARNUM|6768|2009 
Ref_9|TRAN|ROBINSON|67871|1122 

File2.csv

SID|Values 
TRAROB|Ref_1,Ref_2,Ref_3,Ref_4,Ref_9 
MCKBAR|Ref_5,Ref_6,Ref_7,Ref_8 

XML:

<?xml version="1.0" encoding="utf-8" ?> 
<FeedInfo> 

<Rule> 

<RuleInfo> 
    <RuleName>Rule 1</RuleName> 
</RuleInfo> 

<Rules> 
    <item name ="FirstName" NoOfChars ="ALL" number ="0"/> 
    <item name ="LastName" NoOfChars ="ALL" number ="1"/> 
    <item name ="ID" NoOfChars ="ALL" number ="2" /> 

</Rules> 

</Rule> 


</FeedInfo> 

Я написал следующий код:

static void Main(string[] args) 
    { 
     populate(); 
     rulesReader(); 
    } 

public static Dictionary<string,string> createDictionary(string dataPath) 
    { 
     //creates a dictionary from a file 
     StreamReader sr = new StreamReader(dataPath); 

     Dictionary<string, string> refIdVal = new Dictionary<string, string>(); 

     string line = sr.ReadLine(); 

     while ((line = sr.ReadLine()) != null) 
     { 
      string key = line.Split('|')[0]; 
      int i = line.IndexOf('|',0) + 1; 
      int l = line.Length - i; 
      string value = line.Substring(i,l); 
      refIdVal.Add(key, value); 
     } 

     sr.Close(); 

     return refIdVal; 

    } 
public static Dictionary<string,string> populate() 
    { 

     //populates the dictionary with SID,RefID|values format. 

     string refIdPath = "File1.csv"; 
     string sidPath = "File2.csv"; 

     Dictionary<string, string> final = new Dictionary<string, string>(); 

     Dictionary<string, string> refIdVal = createDictionary(refIdPath); 

     Dictionary<string, string> sidVal = createDictionary(sidPath); 

     foreach (KeyValuePair<string, string> pair in sidVal) 
     { 
      string[] refIdTockens = pair.Value.Split(','); 

      for (int i = 0; i <refIdTockens.Length; i++) 
      { 

       final.Add(pair.Key + "," + refIdTockens[i], refIdVal[refIdTockens[i]]); 
       //Console.WriteLine(pair.Key + "," + refIdTockens[i] + "==" + refIdVal[refIdTockens[i]]+ "==" + i); 
      } 
     } 

     foreach (KeyValuePair<string, string> pair in final) 
     { 
      Console.WriteLine(pair.Key + "==" + pair.Value); 
     } 
     return final; 
    } 

public static Dictionary<string,string> finalOutput(Dictionary<string,string> inputDictionary) 
    { 
     Dictionary<string,string> input = inputDictionary; 

     foreach (KeyValuePair<string, string> pair in input) 
     { 

     } 


     return null; 
    } 

public static Dictionary<String, List<int>> rulesReader() 
    { 
     //reads the rules from xml file and returns a dictionary in <string,list> format. 
     Dictionary<string, List<int>> rulesAndNumbers = new Dictionary<string, List<int>>(); 
     XDocument xDoc = XDocument.Load("rules.xml"); 
     int rulesCount = xDoc.Descendants("RuleName").Count(); 

     string ruleName = null; 
     string ruleValue = null; 
     //List<string> ruleNumbers = new List<string>(); 



     var feedDetails = from feed in xDoc.Descendants("Rule") 
          select new 
          { 
           IndexInfo = feed.Descendants("RuleInfo").Descendants(), 
           IndexRules = feed.Descendants("Rules").Descendants() 
          }; 

     foreach (var feed in feedDetails) 
     { 
      foreach (XElement xe in feed.IndexInfo) //RuleName 
      { 
       List<int> ruleNumbers = new List<int>(); 
       ruleName = xe.Value; 

       foreach (XElement xe1 in feed.IndexRules) 
       { 
        ruleValue = xe1.Attribute("number").Value; 
        ruleNumbers.Add(Int32.Parse(ruleValue)); 
        Console.WriteLine(ruleName + "==" + ruleValue); 

       } 

       rulesAndNumbers.Add(ruleName, ruleNumbers); 
       //ruleNumbers.Clear(); 
      } 
     } 

     return rulesAndNumbers; 
    } 

код выше, дает мне словарь в этом формате:

SID, RefID == FirstName | LastName | ID | DOB (KEY == VALUE)

SidRefID словарь

TRAROB,Ref_1==KEN|CARPENTER|67814|1122 
TRAROB,Ref_2==TRAN|ROBINSON|67814|1122 
TRAROB,Ref_3==TRAN|ROBINSON|67871|1122 
TRAROB,Ref_4==TRAN|ROBINSON|67871|1122 
MCKBAR,Ref_5==LAWSN|PERDUE|6761|2009 
MCKBAR,Ref_6==MCKEN|BARNUM|6761|2009 
MCKBAR,Ref_7==MCKEN|BARNUM|6768|2009 
MCKBAR,Ref_8==MCKEN|BARNUM|6768|2009 
TRAROB,Ref_9==TRAN|ROBINSON|67871|1122 

и Dictiona чень как этот XML словарь

[Rule1|0] 
[Rule1|1] 
[Rule1|2] 

Теперь, после того, как все это я застрял здесь: Мне нужно, чтобы соответствовать все значения с с той же частичной KEY т.е. SID или Key.split (,) [0] , В конечном словаре, на основе номеров, упомянутых в XML. 0-я, 1-я и 2-я позиции массива после разделения значений должны быть объединены.

Я уже создал XML-словарь в строковом, List (int) формате. Таким образом, Ref_1 должен совпадать с Ref_2, Ref3, Ref_4 на основе (0,1,2), т.е. конкатенации firstName, LastName, ID. Пихта пример:

Ref1, REF_2, REF3, Ref_4 все имеют тот же SID (SidRefId словарь) поэтому мне нужно, чтобы соответствовать

KENCARPENTER67814 с TRAYROBINSON67814 & TRAYROBINSON67871 & TRAYROBINSON67871 & TRAYROBINSON67871 которая возвращает FALSE для KENCARPENTER67814, потому что ни один из строка соответствует друг с другом, Аналогично желаемый результат:

RULE1,TRAROB,Ref_1==KEN|CARPENTER|67814|1122|FALSE 
RULE1,TRAROB,Ref_2==TRAN|ROBINSON|67814|1122|FALSE 
RULE1,TRAROB,Ref_3==TRAN|ROBINSON|67871|1122|TRUE 
RULE1,TRAROB,Ref_4==TRAN|ROBINSON|67871|1122|TRUE 
RULE1,MCKBAR,Ref_5==LAWSN|PERDUE|6761|2009|FALSE 
RULE1,MCKBAR,Ref_6==MCKEN|BARNUM|6761|2009|FALSE 
RULE1,MCKBAR,Ref_7==MCKEN|BARNUM|6768|2009|TRUE 
RULE1,MCKBAR,Ref_8==MCKEN|BARNUM|6768|2009|TRUE 
RULE1,TRAROB,Ref_9==TRAN|ROBINSON|67871|1122|TRUE 

Я думал сделать копию SidRefId и сопоставляя их друг с другом, но это займет много времени для больших файлов и нескольких правил в XML-файле, с которыми я собираюсь иметь дело.

Может ли кто-нибудь сказать мне эффективный способ сделать это? Благодаря!

ответ

0

Для меня это похоже, что вы пытаетесь разработать свой собственный движок для записи ссылок. То есть для поиска повторяющихся записей, которые не являются точными дубликатами. Если бы я был вами, я бы не попытался создать свой собственный движок, а вместо этого использовал только один из уже существующих.

У Википедии был список таких движков, но он удалился, и я не знаю никаких других списков, поэтому я просто свяжусь с тем, что я сделал: Duke. Есть и другие двигатели.

Если вы настаиваете на этом, один из способов сделать это - это то, что вы здесь делаете: создайте ключ для каждой записи, затем сгруппируйте по клавише. Однако это довольно примитивно, поэтому вы должны стремиться выполнять более подробное сопоставление после того, как вы сопоставили ключ. Простое совпадение по ключу вызывает много ложных срабатываний.

Более сложный подход заключается в том, чтобы делать то, что я сделал: индексировать данные с помощью поисковой системы, такой как Lucene, затем искать похожие записи и выполнять детальное сравнение с кандидатами. Или вы можете использовать чувствительное к местоположению хеширование. Или метрические пространства. Или индексы на основе q-грамм.

Смежные вопросы