Лучший способ найти, какая ячейка массива строк содержит текст
У меня есть блок текста, который я беру из файла Gedcom ( здесь и здесь)
Текст плоский и в основном разбит на "узлы"
Я делю каждый узел на символе \r и таким образом делю его на каждую из его частей (количество "линий" может варьироваться)
Я знаю, что адрес 0 всегда будет идентификатором, но после этого все может быть где угодно, поэтому я хочу протестировать каждую ячейку массива, чтобы увидеть, содержит ли она правильный тег для обработки
пример того, как будут выглядеть два узла
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
Итак, когда я закончил, у меня есть массив, который выглядит как
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 ответа
Может использовать статический метод 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);
Как насчет простого регулярного выражения?
^(\d)\s=\s\"\d\s(SEX|BIRT|FAMS){1}.*$
Первая группа захватывает адрес, вторая группа тег.
Кроме того, может быть быстрее выгрузить все элементы массива в строку и выполнить регулярное выражение для всего лота одновременно.
Цикл for в методе FindIndexinArray shd прерывается, когда вы находите совпадение, если вас интересует только первое совпадение.
"Но это кажется неэффективным, потому что я в итоге вызываю его дважды, чтобы убедиться, что он не возвращает -1"
Скопируйте возвращенное значение в переменную перед тестированием, чтобы предотвратить несколько вызовов.
IndexResults = FindIndexinArray(SubNode, "1 BIRT ")
if (IndexResults != -1)
{
// add birthday to Struct
I.BirthDay = SubNode[IndexResults].Replace("2 DATE ", "").Trim();
}