2016-04-11 10 views
3

これを前に説明すると、私はデータベースからレコードを引き出しています。 CaseNumber列には一意の識別子があります。しかし、ONEイベントに関連する複数のケースは、非常に類似したケース番号を持ち、最後の2桁が次の番号になります。例:文字列を特定して正しく操作する

TR42X2330789 
TR42X2330790 
TR42X2330791 
TR51C0613938 
TR51C0613939 
TR51C0613940 
TR51C0613941 
TR51C0613942 
TR52X4224749 

これらのレコードを3つのグループに分類する必要があります。現在のところ、私の機能は本当に面倒です。ケース番号のグループの後にケース番号の別のグループが続くシナリオは説明しません。私は誰かがこれにどのように取り組むべきかについて何か提案があったかどうか疑問に思っていた。すべてのケース番号を配列に入れることを考えていました。

int i = 1; 
string firstCaseNumber = string.Empty; 
string previousCaseNumber = string.Empty; 

if (i == 1) 
{ 
    firstCaseNumber = texasHarrisPublicRecordInfo.CaseNumber; 

    i++; 
} 
else if (i == 2) 
{ 
    string previousCaseNumberCode = firstCaseNumber.Remove(firstCaseNumber.Length - 3); 
    int previousCaseNumberTwoCharacters = Int32.Parse(firstCaseNumber.Substring(Math.Max(0, firstCaseNumber.Length - 2))); 

    string currentCaseNumberCode = texasHarrisPublicRecordInfo.CaseNumber.Remove(texasHarrisPublicRecordInfo.CaseNumber.Length - 3); 
    int currentCaselastTwoCharacters = Int32.Parse(texasHarrisPublicRecordInfo.CaseNumber.Substring(Math.Max(0, texasHarrisPublicRecordInfo.CaseNumber.Length - 2))); 

    int numberPlusOne = previousCaseNumberTwoCharacters + 1; 

    if (previousCaseNumberCode == currentCaseNumberCode && numberPlusOne == currentCaselastTwoCharacters) 
    { 
     //Group offense here 

     i++; 

     needNewCriminalRecord = false; 
    } 
    else 
    { 
     //NewGRoup here 
    } 
    previousCaseNumber = texasHarrisPublicRecordInfo.CaseNumber; 
    i++; 
} 
else 
{ 
    string beforeCaseNumberCode = previousCaseNumber.Remove(previousCaseNumber.Length - 3); 
    int beforeCaselastTwoCharacters = Int32.Parse(previousCaseNumber.Substring(Math.Max(0, previousCaseNumber.Length - 2))); 

    string currentCaseNumberCode = texasHarrisPublicRecordInfo.CaseNumber.Remove(texasHarrisPublicRecordInfo.CaseNumber.Length - 3); 
    int currentCaselastTwoCharacters = Int32.Parse(texasHarrisPublicRecordInfo.CaseNumber.Substring(Math.Max(0, texasHarrisPublicRecordInfo.CaseNumber.Length - 2))); 

    int numberPlusOne = beforeCaselastTwoCharacters + 1; 

    if (beforeCaseNumberCode == currentCaseNumberCode && numberPlusOne == currentCaselastTwoCharacters) 
    { 
     i++; 

     needNewCriminalRecord = false; 
    } 
    else 
    { 
     needNewCriminalRecord = true; 
    } 
} 
+0

あなたは、エンティティのクラスを提供することができ、どのようにあなたがあなたの関数を使うのですか? – Valentin

答えて

0

私は、一般的なpuropose拡張メソッド作成します。

static IEnumerable<IEnumerable<T>> GroupByConsecutiveKey<T, TKey>(this IEnumerable<T> list, Func<T, TKey> keySelector, Func<TKey, TKey, bool> areConsecutive) 
{ 
    using (var enumerator = list.GetEnumerator()) 
    { 
     TKey previousKey = default(TKey); 
     var currentGroup = new List<T>(); 

     while (enumerator.MoveNext()) 
     { 
      if (!areConsecutive(previousKey, keySelector(enumerator.Current))) 
      { 
       if (currentGroup.Count > 0) 
       { 
        yield return currentGroup; 
        currentGroup = new List<T>(); 
       } 
      } 

      currentGroup.Add(enumerator.Current); 
      previousKey = keySelector(enumerator.Current); 
     } 

     if (currentGroup.Count != 0) 
     { 
      yield return currentGroup; 
     } 
    } 
} 

をそして今、あなたはそれが好きで使用します。

var grouped = data.GroupByConsecutiveKey(item => item, (k1, k2) => areConsecutive(k1, k2)); 

areConsecutiveのクイックハックは以下のようになります。

public static bool Consecutive(string s1, string s2) 
{ 
    if (s1 == null || s2 == null) 
     return false; 

    if (s1.Substring(0, s1.Length - 2) != s2.Substring(0, s2.Length - 2)) 
     return false; 

    var end1 = s1.Substring(s1.Length - 2, 2); 
    var end2 = s2.Substring(s2.Length - 2, 2); 

    if (end1[1]!='0' && end2[1]!='0') 
     return Math.Abs((int)end1[1] - (int)end2[1]) == 1; 

    return Math.Abs(int.Parse(end1) - int.Parse(end2)) == 1; 
} 

Keyはどんな形を取ることもできると考えています。英数字コードが常に同じパターンを持っている場合は、おそらくこのメソッドをよりきれいにするか、正規表現だけを使用することができます。

1

パフォーマンスについて本当に気にしない場合は、LINQ .GroupBy().ToDictionary()メソッドを使用して、リスト付き辞書を作成できます。行の間で何か:

string[] values = 
{ 
    "TR42X2330789", 
    "TR42X2330790", 
    "TR42X2330791", 
    "TR51C0613938", 
    "TR51C0613939", 
    "TR51C0613940", 
    "TR51C0613941", 
    "TR51C0613942", 
    "TR52X4224749" 
}; 

Dictionary<string, List<string>> grouppedValues = values.GroupBy(v => 
      new string(v.Take(9).ToArray()), // key - first 9 chars 
       v => v)      // value 
        .ToDictionary(g => g.Key, g => g.ToList()); 

foreach (var item in grouppedValues) 
{ 
    Console.WriteLine(item.Key + " " + item.Value.Count); 
} 

出力:

TR42X2330 3 
TR51C0613 5 
TR52X4224 1 
+0

これは、私がIdsを格納している文字列のリストに関連付けるディクショナリを使用していたことです。ヘルプマンに感謝します。 'var criminalRecordsToCaseNumbers =新しい辞書>();' – Lostaunaum

+0

@Lostaunaumようこそ – Fabjan