Perl- Какую функцию я ищу? Присвоение нескольких правил указанному результату

arrays linux perl

90 просмотра

3 ответа

Я концептуализировал функцию в своей голове, и я думаю, что она существует, но если это так, я не знаю ее название, и по этой причине трудно гуглить.

Допустим, я хочу определить два результата - я позвоню им PassиFail

Я хочу применить несколько разных правил к каждому из двух результатов.

Итак, для ясности (будем надеяться) предположим, что у меня есть файл с разными годами в каждой строке или пробелы.

файл

line1    1978
line2    1989
line3    
line4    1978
line5    1999
line6    
line7    1768

Теперь предположим, что есть пользовательский ввод 1978для сравнения с файлом.

Эта дата будет сравниваться с каждой строкой в ​​файле.

На основе сравнения может быть только два результата: они есть Passи Fail.

Чтобы сравнение было в Passгруппе, оно должно соответствовать следующим критериям:

1) It matches the year in the file
2) Neither the input, or the line in the file contains a year
3) Only one line contains a year, and the other is blank

Чтобы линия соответствовала Failусловию:

1) Both the input and the file record contain a year, but they are different. 

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

line1    1978   Pass
line2    1989   Fail
line3           Pass
line4    1978   Pass
line5    1999   Fail 
line6           Pass
line7    1768   Fail

Так что, в основном, я хочу назначить другое (и множественное) условие Passи Failкак описано выше.

То, что я хочу знать, это то, что (если что-нибудь) является именем этого типа функции.

Как называется какая-то функция, где я могу применить эти правила к Passи Fail. Насколько я знаю, я не могу создавать Passи Failпеременные, потому что есть несколько правил для каждого условия. Есть ли какая-то другая встроенная функция, которую я могу использовать?

Автор: neilH Источник Размещён: 08.11.2019 11:27

Ответы (3)


3 плюса

Решение

Это должно помочь вам. Он просто проверяет каждую строку на наличие неисправности. Все остальное - пропуск.

use strict;
use warnings 'all';

my $input = 1978;

while ( my $line = <DATA> ) {

    $line =~ s/\s*\z//;

    my $result = $line && $input && $line ne $input ? 'Fail' : 'Pass';

    printf "%4s %s\n", $line, $result;
}


__DATA__
1978
1989

1978
1999

1768

выход

1978 Pass
1989 Fail
     Pass
1978 Pass
1999 Fail
     Pass
1768 Fail
Автор: Borodin Размещён: 20.08.2016 04:38

2 плюса

Почему строка 5 совпадает? Ввод 1978 и файл содержит 1999? [Ах, вы только что отредактировали свой вопрос, чтобы исправить это]

С условием, что мой код возвращает false для этого соответствия (что мне кажется правильным). Вот моя версия:

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

my @years = (1978, 1989, undef, 1978, 1999, undef, 1768);
my $year = 1978;

say compare($year, \@years);

sub compare {
  my ($year, $years) = @_;
  my @return;

  foreach (@$years) {
    push @return, 1 and next if ! defined $_;
    push @return, 1 and next if $_ == $year;
    push @return, 0;
  }

  return @return;
}
Автор: Dave Cross Размещён: 20.08.2016 03:50

0 плюса

Там нет стандартной библиотечной функции или имени именно для того, что вы описали. У вас есть два массива, и вы хотите сравнить их элементы, используя сложные критерии. Существует бесконечное количество способов сравнения двух массивов с использованием сложных критериев; мы не можем создать быстрое имя и написать стандартную библиотечную функцию для всех них!

Используя минимальные предположения, мы можем написать эту функцию следующим образом:

sub compareArrayElementsForEitherBlankSpaceOrMatch {
    ## takes two array references to compare; assumes they're the same length
    my ($A,$B) = @_;
    my @res;
    if (@$A > 0) {
        $#res = @$A-1; ## preallocate array
        for (my $i = 0; $i < @$A; ++$i) {
            $res[$i] = $A->[$i] eq ' ' || $B->[$i] eq ' ' || $A->[$i] eq $B->[$i] ? 1 : 0;
        }
    }
    return @res;
}

Демо-версия:

my @res = compareArrayElementsForEitherBlankSpaceOrMatch(
    [' ', ' ' , 2000, 2000, 2000 ],
    [' ', 2000, ' ' , 2000, 1900 ]
);
print("@res\n");'
## 1 1 1 1 0

Обновление: на основе ваших правок вы сравниваете не два массива друг с другом, а сравниваете один массив с одним значением. Это может быть достигнуто следующим образом:

sub compareArrayElementsForEitherBlankSpaceOrMatch {
    ## takes an array reference and compares its elements with a given value
    ## an element is considered to match if it is blank or equal to the value
    my ($A,$x) = @_;
    my @res;
    if (@$A > 0) {
        $#res = @$A-1; ## preallocate array
        for (my $i = 0; $i < @$A; ++$i) {
            $res[$i] = $A->[$i] =~ m(^\s*$) || $A->[$i] eq $x ? 1 : 0;
        }
    }
    return @res;
}

Демо-версия:

my @res = compareArrayElementsForEitherBlankSpaceOrMatch(
    [1978,1989,"",1978,1999,"",1768],
    1978
);
print("@res\n");
## 1 0 1 1 0 1 0

Обратите внимание, что результат строки 5 должен быть ошибочным, поскольку 1999 год не равен 1978 году.

Я усовершенствовал пустую проверку, чтобы использовать проверку регулярных выражений, m(^\s*$)а не фиксированную проверку на равенство для одного пробела.

Мой оригинальный комментарий по-прежнему верен в отношении отсутствия стандартной функции или имени для этой точной операции.

Автор: bgoldst Размещён: 20.08.2016 03:40
Вопросы из категории :
32x32