Удалить дубликаты из 2D-массива в Perl

Я думаю, что лучше всего называть 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.

0
задан ran1n 18 January 2019 в 05:22
поделиться

2 ответа

Во-первых: вам действительно следует стараться не использовать устаревший синтаксис 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
0
ответ дан Stefan Becker 18 January 2019 в 05:22
поделиться

Показанная подпрограмма хороша для работы с массивом, который для элементов имеет ссылки на массив. Это действительно основной способ организации 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 ]

0
ответ дан zdim 18 January 2019 в 05:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: