Лучший способ найти, какая ячейка массива строк содержит текст - PullRequest
1 голос
/ 13 мая 2009

У меня есть блок текста, который я беру из Gedcom ( Здесь и Здесь ) Файл

Текст плоский и в основном разбит на "узлы"

Я делю каждый узел на \ r-символе и таким образом делю его на каждую из его частей (количество «линий» может варьироваться)

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

пример того, как будут выглядеть два узла

</p>

<pre><code>0 @ind23815@ INDI <<<<<<<<<<<<<<<<<<< Start of node 1
1 NAME Lawrence /Hucstepe/
2 DISPLAY Lawrence Hucstepe
2 GIVN Lawrence
2 SURN Hucstepe
1 POSITION -850,-210
2 BOUNDARY_RECT (-887,-177),(-813,-257)
1 SEX M
1 BIRT 
2 DATE 1521
1 DEAT Y
2 DATE 1559
1 NOTE     * Born: Abt 1521, Kent, England
2 CONT     * Marriage: Jane Pope 17 Aug 1546, Kent, England
2 CONT     * Died: Bef 1559, Kent, England
2 CONT 
1 FAMS @fam08318@
0 @ind23816@ INDI  <<<<<<<<<<<<<<<<<<<<<<< Start of Node 2
1 NAME Jane /Pope/
2 DISPLAY Jane Pope
2 GIVN Jane
2 SURN Pope
1 POSITION -750,-210
2 BOUNDARY_RECT (-787,-177),(-713,-257)
1 SEX F
1 BIRT 
2 DATE 1525
1 DEAT Y
2 DATE 1609
1 NOTE     * Born: Abt 1525, Tenterden, Kent, England
2 CONT     * Marriage: Lawrence Hucstepe 17 Aug 1546, Kent, England
2 CONT     * Died: 23 Oct 1609
2 CONT 
1 FAMS @fam08318@
0 @ind23817@ INDI  <<<<<<<<<<< start of Node 3
</code>

Итак, когда я закончу, у меня будет массив, который выглядит как

address , string
0 = "1 NAME Lawrence /Hucstepe/"
1 = "2 DISPLAY Lawrence Hucstepe"
2 = "2 GIVN Lawrence"
3 = "2 SURN Hucstepe"
4 = "1 POSITION -850,-210"
5 = "2 BOUNDARY_RECT (-887,-177),(-813,-257)"
6 = "1 SEX M"
7 = "1 BIRT "
8 = "1 FAMS @fam08318@"

Таким образом, мой вопрос заключается в том, каков наилучший способ поиска в вышеуказанном массиве, чтобы увидеть, какая ячейка имеет тег SEX, тег NAME или тег FAMS

это код, который у меня есть

private int FindIndexinArray(string[] Arr, string search)
{
    int Val = -1;
    for (int i = 0; i < Arr.Length; i++)
    {
        if (Arr[i].Contains(search))
        {
            Val = i;
        }
    }
    return Val;
}

Но это кажется неэффективным, потому что я в итоге вызываю его дважды, чтобы убедиться, что он не возвращает -1

Вот так

if (FindIndexinArray(SubNode, "1 BIRT ") != -1) { // add birthday to Struct I.BirthDay = SubNode[FindIndexinArray(SubNode, "1 BIRT ") + 1].Replace("2 DATE ", "").Trim(); }

извините, это более длинный пост, но, надеюсь, у вас, ребята, будет совет специалиста

Ответы [ 4 ]

3 голосов
/ 13 мая 2009

Может использовать статический метод FindAll класса Array: Тем не менее, он вернет саму строку, если это сработает ..

string[] test = { "Sex", "Love", "Rock and Roll", "Drugs", "Computer"};
Array.FindAll(test, item => item.Contains("Sex") || item.Contains("Drugs") || item.Contains("Computer"));

=> обозначает лямда-выражение. В основном метод без конкретной реализации. Вы также можете сделать это, если лямда дает вам мурашки.

//Declare a method 

     private bool HasTag(string s)
     {
         return s.Contains("Sex") || s.Contains("Drugs") || s.Contains("Computer");
     }

     string[] test = { "Sex", "Love", "Rock and Roll", "Drugs", "Computer"};
     Array.FindAll(test, HasTag);
3 голосов
/ 13 мая 2009

А как насчет простого регулярного выражения ?

^(\d)\s=\s\"\d\s(SEX|BIRT|FAMS){1}.*$

Первая группа захватывает адрес, вторая группа - тег.

Кроме того, может быть быстрее выгрузить все элементы массива в строку и выполнить регулярное выражение для всего лота одновременно.

0 голосов
/ 13 мая 2009

Цикл for в методе FindIndexinArray shd прерывается, когда вы находите совпадение, если вас интересует только первое совпадение.

0 голосов
/ 13 мая 2009

"Но это кажется неэффективным, потому что я в итоге вызываю его дважды, чтобы убедиться, что он не возвращает -1"

Скопируйте возвращенное значение в переменную перед проверкой, чтобы предотвратить множественные вызовы.

IndexResults = FindIndexinArray(SubNode, "1 BIRT ")
if (IndexResults != -1)
        {
            // add birthday to Struct 
            I.BirthDay = SubNode[IndexResults].Replace("2 DATE ", "").Trim();
        }
...