2014-11-27 3 views
0

Как я могу сбросить значения хэш в PerlКак изменить значения хеша с новыми значениями в perl?

use warnings; 
use strict; 
my %hash = qw(one 1 two 2 three 3 four 4); 
my @key = keys(%hash); 
my @avz = (9..12); 
my %vzm; 
print "Original hash and keys : ",%hash,"\n"; 
for(my $i = 0; $i<=scalar @avz; $i++){ 
    my @new = "$key[$i] $avz[$i] "; 
    push(%vzm , @new); 
} 
print "modified hash and keys",%vzm,"\n"; 

Я попытался изменить ключи оригинального хеша с другими клавишами. Как я могу сделать это Эта программа дает ошибку является:

Original hash and keys : three3one1two2four4 
Not an ARRAY reference at key.pl line 10. 

Я ожидаю, что выход

Original hash and keys : three3one1two2four4 
modified hash and keys : three11one9two10four12 

Как я могу это сделать

+1

Вы пытаетесь нажать кнопку HASH, нажмите для ARRAYs –

+0

@sputnick Что я могу попробовать для хэшей? – mkHun

+1

Обязательно ознакомьтесь с ['perldsc'] (http://perldoc.perl.org/perldsc.html), который является основной ссылкой на документацию. Perl Maven имеет [довольно хорошее базовое резюме хэшей] (http://perlmaven.com/perl-hash). –

ответ

1

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

my @tmp = qw(one 1 two 2 three 3 four 4); 
my %hash = @tmp; 
# 'one', 'two', .. 
my @key = @tmp[ grep !($_%2), 0 .. $#tmp ]; 


# .. 
for my $i (0 .. $#avz) { 

    $vzm{ $key[$i] } = $avz[$i]; 
} 

или с использованием хэш-срез как более perlish подход,

@vzm{ @key } = @avz; 
+0

Он дает выход 'three9one10two11four12'. – mkHun

+0

Я ожидаю, что выход будет' three11one9two10four12' – mkHun

+0

@Hussain ваши ключи неупорядочены, проверьте обновление. –

1

Чтобы создать хэш-элемент, можно использовать назначение до $var{$key}.

for (my $i = 0; $i < scalar @avz; $i++) { 
    $vzm{$key[$i]} = $avz[$i]; 
} 

Заметим также, что условие цикла должно быть <, не <=. Индексы списка/массива заканчиваются на scalar @avz - 1.

+0

дает три9one10two11four12 – mkHun

+0

Порядок ключей в хеше произволен. Взгляните на порядок в «Оригинальном хеше и клавишах». – Barmar

+0

Я ожидаю, что выход будет 'three11one9two10four12' – mkHun

1

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

my @key = keys(%hash); 

потребности быть таким:

my @key = ('one', 'two', 'three', 'four'); 

После того, как вы есть, что вы можете просто присвоить значения сразу с хэш-срезе:

my %vzm; 
@vzm{@key} = @avz; 
+1

oops, сначала не получилось это правильно – ysth

2

Итак, сначала вы делаете что-то неприятное в своем коде:

Вы пытаетесь взять упорядоченную структуру данных - a rray - и вставьте его в структуру данных с ключами, которая не имеет определенного порядка упорядочения.

Это не будет работать очень хорошо - это технически работает, потому что внутренне perl обрабатывает массивы и хеши аналогично.

Но, например, ваше первое задание - то, что вы на самом деле получают:

my %hash = (
    one => 1, 
    two => 2, 
    three => 3, 
    four => 4 
); 

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

Для добавления элементов в массив:

$hash{'nine'} = 9; 

Чтобы удалить элементы из вашего массива:

delete ($hash{'one'}); 

Вы можете перебирать на keys или values - и в сочетании с sort даже сделать их в какой-то порядка. (Просто помните, что для сортировки буквенно-цифровых чисел у вас будет собственное задание сортировки).

foreach my $key (sort keys %hash) { 
    print "$key => $hash{$key}\n"; 
} 

(Примечание - это сортировка по буквенно-цифровой строкой, поэтому дает:

four => 4 
one => 1 
three => 3 
two => 2 

Если вы хотите отсортировать по значению:

foreach my $key (sort { $hash{$a} <=> $hash{$b} } keys %hash) { 
    print "$key => $hash{$key}\n"; 
} 

И так вы получите:

one => 1 
two => 2 
three => 3 
four => 4 

Так что реальный вопрос rema ins - что вы на самом деле пытаетесь выполнить? Точка хеша должна предоставить вам неупорядоченную мини-базу данных пар ключ-значение. Рассмотрение одного, как массив, не имеет большого смысла. Либо вы повторяете элементы хэша в произвольном порядке, либо применяете к нему определенный вид - но тот, где вы полагаетесь на получение элементов в определенном порядке, является плохим планом - он может работать, но это не гарантировано работать, и это делает неправильный код.

+1

++ Кто-то однажды сказал мне, когда вы думаете о данных и обращаетесь к нему так, чтобы предполагать, что некоторые элементы набора данных приходят ** до или после ** некоторые другие - вы думаете о массивах. Когда вы думаете о данных и получаете доступ к ним, ссылаясь на ** схему именования ** для частей набора данных, вы думаете о хешах. Это кажется очевидным, но ключ (не предназначен для каламбуров) - это тщательно подумать о том, как данные и его структура влияют на то, как вы его используете. –

+0

Это правда. Массивы и хеши могут показаться похожими и иметь похожие структуры, но все они касаются модели данных. Я по-прежнему придерживаюсь мнения, что хеши являются одной из самых больших «точек продажи» в Perl - многие языки могут создавать массивы – Sobrique

Смежные вопросы