Я думаю, что лучше всего называть GetOrdinal ("columnName") на вашем DataReader спереди и уловить исключение IndexOutOfRangeException, если столбец отсутствует.
На самом деле, давайте сделаем метод расширения:
public static bool HasColumn(this IDataRecord r, string columnName)
{
try
{
return r.GetOrdinal(columnName) >= 0;
}
catch (IndexOutOfRangeException)
{
return false;
}
}
Edit
Хорошо, этот пост начинает собирать несколько проголосовавших в последнее время, и я не могу удалить его, потому что это принятый ответ, поэтому я собираюсь обновить его и (надеюсь) попытаться оправдать использование обработки исключений в качестве потока управления.
Другой способ достижения этого, поскольку Chad Grant , состоит в том, чтобы перебирать каждое поле в DataReader и проводить сравнение без учета регистра для имени поля, которое вы ищете. Это будет работать очень хорошо, и, по правде говоря, он будет работать лучше, чем мой метод выше. Конечно, я бы никогда не использовал метод выше внутри цикла, где performace была проблемой.
Я могу думать об одной ситуации, в которой метод try / GetOrdinal / catch будет работать там, где этого цикла нет. Это сейчас, однако, совершенно гипотетическая ситуация, так что это очень надуманное оправдание. Независимо от того, медведь со мной и посмотреть, что вы думаете.
Представьте базу данных, которая позволила вам столбцы «псевдоним» в таблице. Представьте, что я мог бы определить таблицу с столбцом «EmployeeName», но также дать ей псевдоним «EmpName», а выбор для любого имени вернет данные в этом столбце.
Теперь представьте, что для этой базы данных есть поставщик ADO.NET, и они закодировали для него реализацию IDataReader, которая учитывает псевдонимы столбцов.
Теперь dr.GetName(i)
(как используется в ответе Чада) может возвращать только одну строку, поэтому она должна возвращать только one из «псевдонимов» в столбце. Тем не менее, GetOrdinal("EmpName")
может использовать внутреннюю реализацию полей этого провайдера для проверки псевдонима каждого столбца для имени, которое вы ищете.
В этой гипотетической ситуации с «псевдонимом столбцов» try / GetOrdinal / catch метод был бы единственным способом убедиться в том, что вы проверяете каждое изменение имени столбца в наборе результатов.
Flimsy? Конечно. Но стоит подумать. Честно говоря, я бы предпочел «официальный» метод HasColumn в IDataRecord.
Во-первых: вам действительно следует стараться не использовать устаревший синтаксис Perl и побочные эффекты.
Второе: ответ зависит от структуры данных, которую вы генерируете из входных данных. Вот два примера реализации:
#!/usr/bin/perl
use strict;
use warnings;
# 2D Array: list of array references
my @data = (
['Rafa', 'Nadal', 'Data1'],
['Goran', 'Ivan', 'Data2'],
['Leander', 'Paes', 'Data2'],
['Leander', 'Paes', 'Data2'],
);
my %seen;
foreach my $unique (
grep {
not $seen{
join('', @{ Во-первых: вам действительно следует стараться не использовать устаревший синтаксис Perl и побочные эффекты.
Второе: ответ зависит от структуры данных, которую вы генерируете из входных данных. Вот два примера реализации:
[110] Вывод:
$ perl dummy.pl
Rafa,Nadal,Data1
Goran,Ivan,Data2
Leander,Paes,Data2
Rafa,Nadal,Data1
Goran,Ivan,Data2
Leander,Paes,Data2
})
}++
} @data
) {
print join(',', @{ $unique }), "\n";
}
print "\n";
# List of "objects", keys are table column names
@data = (
{ first => 'Rafa', last => 'Nadal', data => 'Data1' },
{ first => 'Goran', last => 'Ivan', data => 'Data2' },
{ first => 'Leander', last => 'Paes', data => 'Data2' },
{ first => 'Leander', last => 'Paes', data => 'Data2' },
);
%seen = ();
my @key_order = qw(first last data);
foreach my $unique (
grep {
not $seen{
join('', @{ Во-первых: вам действительно следует стараться не использовать устаревший синтаксис Perl и побочные эффекты.
Второе: ответ зависит от структуры данных, которую вы генерируете из входных данных. Вот два примера реализации:
[110] Вывод:
$ perl dummy.pl
Rafa,Nadal,Data1
Goran,Ivan,Data2
Leander,Paes,Data2
Rafa,Nadal,Data1
Goran,Ivan,Data2
Leander,Paes,Data2
}{ @key_order } )
}++
} @data
) {
print join(',', @{ $unique }{ @key_order }), "\n";
}
Вывод:
$ perl dummy.pl
Rafa,Nadal,Data1
Goran,Ivan,Data2
Leander,Paes,Data2
Rafa,Nadal,Data1
Goran,Ivan,Data2
Leander,Paes,Data2
Показанная подпрограмма хороша для работы с массивом, который для элементов имеет ссылки на массив. Это действительно основной способ организации 2D-данных, где ваши строки - это arrayrefs.
Существуют модули, которые могут быть использованы для этого, но этот старый добрый метод также хорошо работает
use warnings;
use strict;
use Data::Dump qw(dd);
sub uniq_arys {
my %seen;
grep { not $seen{join $;, @ Показанная подпрограмма хороша для работы с массивом, который для элементов имеет ссылки на массив. Это действительно основной способ организации 2D-данных, где ваши строки - это arrayrefs.
Существуют модули, которые могут быть использованы для этого, но этот старый добрый метод также хорошо работает
[110] Печатает как ожидалось (последняя строка пропала), используя Data :: Dump [ 114], чтобы показать данные.
Подпрограмма работает путем объединения каждого массива в строку, а затем они проверяются на наличие дубликатов с использованием хэша. $; является разделителем нижнего индекса , и вместо этого пустая строка ''
вполне подойдет.
Этот подход создает много вспомогательных данных - в принципе, удваивает данные - и, если производительность становится проблемой, может быть лучше просто сравнить поэлементно (ценой сложности). Это может быть проблемой только с довольно большими наборами данных.
Пример модуля: используйте uniq_by
из List :: UtilsBy
use List::UtilsBy qw(uniq_by);
my @no_dupes = uniq_by { join '', @ Показанная подпрограмма хороша для работы с массивом, который для элементов имеет ссылки на массив. Это действительно основной способ организации 2D-данных, где ваши строки - это arrayrefs.
Существуют модули, которые могут быть использованы для этого, но этот старый добрый метод также хорошо работает
[110] Печатает как ожидалось (последняя строка пропала), используя Data :: Dump [ 114], чтобы показать данные.
Подпрограмма работает путем объединения каждого массива в строку, а затем они проверяются на наличие дубликатов с использованием хэша. $; является разделителем нижнего индекса , и вместо этого пустая строка ''
вполне подойдет.
Этот подход создает много вспомогательных данных - в принципе, удваивает данные - и, если производительность становится проблемой, может быть лучше просто сравнить поэлементно (ценой сложности). Это может быть проблемой только с довольно большими наборами данных.
Пример модуля: используйте uniq_by
из List :: UtilsBy
[111] Это более или менее совпадает с подпунктом выше. [1114 ] } @data;
Это более или менее совпадает с подпунктом выше. [1114 ]}++ } @_;
}
my @data = (
[ qw(one two three) ],
[ qw(ten eleven twelve) ],
[ qw(10 11 12) ],
[ qw(ten eleven twelve) ],
);
my @data_uniq = uniq_arys(@data);
dd \@data_uniq;
Печатает как ожидалось (последняя строка пропала), используя Data :: Dump [ 114], чтобы показать данные.
Подпрограмма работает путем объединения каждого массива в строку, а затем они проверяются на наличие дубликатов с использованием хэша. $; является разделителем нижнего индекса , и вместо этого пустая строка ''
вполне подойдет.
Этот подход создает много вспомогательных данных - в принципе, удваивает данные - и, если производительность становится проблемой, может быть лучше просто сравнить поэлементно (ценой сложности). Это может быть проблемой только с довольно большими наборами данных.
Пример модуля: используйте uniq_by
из List :: UtilsBy
use List::UtilsBy qw(uniq_by);
my @no_dupes = uniq_by { join '', @ Показанная подпрограмма хороша для работы с массивом, который для элементов имеет ссылки на массив. Это действительно основной способ организации 2D-данных, где ваши строки - это arrayrefs.
Существуют модули, которые могут быть использованы для этого, но этот старый добрый метод также хорошо работает
[110] Печатает как ожидалось (последняя строка пропала), используя Data :: Dump [ 114], чтобы показать данные.
Подпрограмма работает путем объединения каждого массива в строку, а затем они проверяются на наличие дубликатов с использованием хэша. $; является разделителем нижнего индекса , и вместо этого пустая строка ''
вполне подойдет.
Этот подход создает много вспомогательных данных - в принципе, удваивает данные - и, если производительность становится проблемой, может быть лучше просто сравнить поэлементно (ценой сложности). Это может быть проблемой только с довольно большими наборами данных.
Пример модуля: используйте uniq_by
из List :: UtilsBy
[111] Это более или менее совпадает с подпунктом выше. [1114 ] } @data;
Это более или менее совпадает с подпунктом выше. [1114 ]