Лучший способ получить четкий список телефонных номеров (без удаления оригинального форматирования)? - PullRequest
1 голос
/ 13 февраля 2012

У нас есть основная Person запись и один (или более) дубликат Persons, и мы объединяем их данные, отдавая приоритет мастеру над дубликатом (ами).

Когда дело доходит до телефонных номеров, цель состоит в том, чтобы объединить их данные, используя один телефонный номер в поле Phone, а любые другие телефонные номера - в поле примечаний (чтобы не отбросить их полностью). Записи могут содержать или не содержать номер телефона.

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

(1234) 123123
1234 123123

Это было бы легко, если бы мы могли просто отбросить форматирование и пробелы, но нам нужно сохранить их (за исключением пробелов в начале / конце).

Мы начали с создания Структуры (не знаю, почему у нас есть Структура против Класса, но в любом случае)

Friend Structure PhoneNumber

Private _Raw As String
Public Property Raw() As String
    Get
        Return _Raw
    End Get
    Set(ByVal value As String)
        _Raw = value
    End Set
End Property


Private _Stripped As String
Public Property Stripped() As String
    Get
        Return _Stripped
    End Get
    Set(ByVal value As String)
        _Stripped = value
    End Set
End Property


Sub New(ByVal num As String)
    Raw = num
    Dim RegexObj As New System.Text.RegularExpressions.Regex("[^\d]")
    Stripped = RegexObj.Replace(num, "")
    MsgBox(num & vbCrLf & Stripped)

End Sub
End Structure

Тогда код слияния выглядит так:

    Dim phones As New List(Of PhoneNumber)
    If master.Phone.Trim.Length > 1 Then
        phones.Add(New PhoneNumber(master.Phone.Trim))
    End If
    For Each x As Person In duplicates
        If x.Phone.Trim.Length > 1 And Not phones.Contains(New PhoneNumber(x.Phone.Trim)) Then
            phones.Add(New PhoneNumber(x.Phone.Trim))
        End If
    Next
    If phones.Count > 0 Then
        master.Phone = phones(0).Raw
    End If
    For i = 1 To phones.Count - 1
        master.Notes &= vbCrLf & "Alt. Phone: " & phones(i).Raw
    Next

Но, очевидно, проблема здесь в том, что она допускает дубликаты.

Мы хотим, чтобы Contains соответствовал только «раздетым» значениям, но, конечно, он не знает, как это сделать.

Это уже кажется слишком большим количеством кода для такой незначительной функции, но в данный момент мы смотрим на написание чего-то (в Структуре?), Которое заменит Contains и будет соответствовать только для раздетых. Есть ли более аккуратный способ?

Код в VB, но ответы на C # приветствуются.

Помните также, что мы должны расставить приоритеты мастера, поэтому, если мы используем LINQ и Distinct, нам нужно убедиться, что мы не потеряем порядок сортировки (это мое понимание).

1 Ответ

1 голос
/ 13 февраля 2012

Выяснил, что лучший способ сделать это - использовать Dictionary.Таким образом, мы можем обойтись без структуры и использовать поиск по словарю как по ключу (выделенный номер телефона), так и по значению (отформатированный оригинал).

Примерно так:

    Dim RegexObj As New System.Text.RegularExpressions.Regex("[^\d]")
    Dim phones As New Dictionary(Of String, String)
    master.Phone = master.Phone.Trim
    If master.Phone.Length > 1 Then
        phones.Add(RegexObj.Replace(master.Phone, ""), master.Phone)
    End If
    For Each x As Person In duplicates
        x.Phone = x.Phone.Trim
        If x.Phone.Length > 1 And Not phones.ContainsKey(RegexObj.Replace(x.Phone, "")) Then
            phones.Add(RegexObj.Replace(x.Phone, ""), x.Phone)
        End If
    Next
    If phones.Count > 0 Then
        master.Phone = phones.First.Value
        phones.Remove(phones.First.Key)
    End If
    For Each entry As KeyValuePair(Of String, String) In phones
        master.Notes &= IIf(String.IsNullOrEmpty(master.Notes.Trim), "", vbCrLf).ToString _
            & "Alt. Phone: " & entry.Value
    Next
...