Что лучший способ состоит в том, чтобы удалить значение из массива в Perl?

Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.

Например, ниже - класс ученика, который будет использовать его в нашем коде.

public class Student {

    private int id;

    public int getId() {
        return this.id;
    }

    public setId(int newId) {
        this.id = newId;
    }
}

Приведенный ниже код дает вам исключение с нулевым указателем.

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}

Поскольку вы используете Obj_Student, но вы забыли инициализировать его, как в правильном коде, показанном ниже:

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student = new Student();
            obj_Student.setId(12);
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}
77
задан Sam 17 August 2014 в 14:44
поделиться

5 ответов

Используйте соединение встык, если Вы уже знаете индекс элемента, Вы хотите удалить.

Grep работает, если Вы ищете.

Если необходимо сделать многие из них, Вы получите намного лучшую производительность, если Вы сохраните свой массив в отсортированном порядке, так как можно затем сделать двоичный поиск для нахождения необходимого индекса.

Если это имеет смысл в Вашем контексте, можно хотеть рассмотреть использование "волшебного значения" для удаленных записей, скорее затем удаляя их, экономить на перемещении данных - набор удалил элементы к undef, например. Естественно, это имеет его собственные проблемы (если необходимо знать число "живых" элементов, необходимо отслеживать его отдельно, и т.д.), но может стоить проблемы в зависимости от приложения.

Редактирование На самом деле теперь, когда я бросаю второй взгляд - не использует grep код выше. Было бы более эффективно найти индекс элемента, который Вы хотите удалить, затем использовать соединение встык для удаления его (код, который Вы имеете, накапливает все результаты несоответствия..)

my $index = 0;
$index++ until $arr[$index] eq 'foo';
splice(@arr, $index, 1);

Это удалит первое вхождение. Удаление всех случаев очень похоже, кроме Вас захочет получить все индексы в одной передаче:

my @del_indexes = grep { $arr[$_] eq 'foo' } 0..$#arr;

Остальное оставляют, поскольку осуществление для читателя - помнит, что массив изменяется, поскольку Вы соединяете его!

John Siracusa Edit2 правильно указал, что у меня была ошибка в моем примере.. фиксированный, извините об этом.

85
ответ дан SquareCog 24 November 2019 в 10:58
поделиться

соединение встык удалит элемент (элементы) массива индексом. Используйте grep, как в Вашем примере, чтобы искать и удалить.

13
ответ дан spoulson 24 November 2019 в 10:58
поделиться

Это - что-то, что Вы собираетесь быть выполнением много? Если так, можно хотеть рассмотреть различную структуру данных. Grep собирается искать целый массив, каждый раз и для большого массива мог быть довольно дорогостоящим. Если скорость является проблемой тогда, можно хотеть рассмотреть использование Хеша вместо этого.

В Вашем примере, ключ был бы числом, и значение будет количеством элементов того числа.

8
ответ дан tvanfosson 24 November 2019 в 10:58
поделиться

Если Вы знаете индекс массива, Вы можете удалять () он. Различие между соединением встык () и удаляет (), это удаляет (), не перенумеровывает остающиеся элементы массива.

0
ответ дан Powerlord 24 November 2019 в 10:58
поделиться

Я думаю, что Ваше решение является простым и самым удобным в сопровождении.

Остальная часть сообщения документирует трудность превращения тестов на элементах в splice смещения. Таким образом, делая это более полным ответом.

Посмотрите на циркуляции, до которых необходимо пойти, имеют эффективное (т.е. одна передача) алгоритм для превращения тестов на элементах списка в индексы. И дело не в этом интуитивный вообще.

sub array_remove ( \@& ) { 
    my ( $arr_ref, $test_block ) = @_;
    my $sp_start  = 0;
    my $sp_len    = 0;
    for ( my $inx = 0; $inx <= $#$arr_ref; $inx++ ) {
        local $_ = $arr_ref->[$inx];
        next unless $test_block->( $_ );
        if ( $sp_len > 0 && $inx > $sp_start + $sp_len ) {
            splice( @$arr_ref, $sp_start, $sp_len );
            $inx    = $inx - $sp_len;
            $sp_len = 0;
        }
        $sp_start = $inx if ++$sp_len == 1;
    }
    splice( @$arr_ref, $sp_start, $sp_len ) if $sp_len > 0;
    return;
}
3
ответ дан 6 revs, 2 users 98% 24 November 2019 в 10:58
поделиться
Другие вопросы по тегам:

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