سؤال

أحاول تقليل عدد خطوط التعليمات البرمجية التي أستخدمها ولكنني انتهى بي الأمر بمشكلة بسيطة إلى حد ما (على الرغم من أنها تتجول لي منذ أن بدأت في لف رأسي حول المراجع)

أحاول تسلسل العديد من القيم بترتيب معين .. رمزتي تبدو هكذا ..

my $separator = ":";
my @vals = qw(name last-name first-name phone);
my $return_name;
$return_name = map { 
    $return_name = $return_name . $query->param($_) . $separator 
} @vals;

ما أحصل عليه هو "4" ، بدلاً من concantenening الكل في سلسلة واحدة.

ما أحاول تحقيقه هو نسخة أقصر من ...

$return_name = $query->param('name') . 
    $separator . $query->param('last-name') . 
    $separator . $query->param('first_name') . 
    $separator . $query->param('phone');

(أحاول فعليًا أن أحصل على حوالي 25 $query->params. أعطيت أربعة فقط للإيجاز)

هل كانت مفيدة؟

المحلول

جزء من مشكلتك هو الارتباك حول كيفية map يعمل.

map يأخذ قائمة بالوسائط ، ويقوم بإجراء عملية على عناصر القائمة وإنشاء قائمة جديدة من النتائج. في سياق القياسي ، يعيد عدد الأعضاء في القائمة الجديدة.

في معظم الحالات ، لا تريد القيام بمهمة في map عملية.

# no assignment needed to set @foo
my @foo = map $_+2, 1,2,3; 
# @foo = (3,4,5);

المكان الوحيد الذي يكون فيه المهمة منطقيًا هو إذا كنت بحاجة إلى استخدام عملية من شأنها تغيير قيمة $_, ، لكنك تحتاج إلى الحفاظ على الحجج لتحديد خريطة دون تغيير.

هذا التفسير ليس واضحا بشكل رهيب. تحقق من هذه الأمثلة ، يجب أن تساعد في توضيح ما أقوله. يمكن للعروض الأولى التي تعرضها خريطة تغيير القيم التي تعالجها:

my @foo = qw( fee fie foe fum );
my @bar = map { s/e/-/g } @foo;
# @foo = ( 'f--', 'fi-', 'fo-', 'fum' ); 
# @bar = ( 2, 1, 1, '' );

لتجنب تغيير foo يمكنك القيام به:

my @foo = qw( fee fie foe fum );
my @bar = map { my $val = $_; $val =~ s/e/-/g } @foo;
# @foo = ( 'fee', 'fie', 'foe', 'fum' ); 
# @bar = ( 'f--', 'fi-', 'fo-', 'fum' ); 

أو يمكنك أن تفعل:

استخدام القائمة :: moreutils QW (تطبيق) ؛

my @foo = qw( fee fie foe fum );
my @bar = apply { s/e/-/g } @foo;
# @foo = ( 'fee', 'fie', 'foe', 'fum' ); 
# @bar = ( 'f--', 'fi-', 'fo-', 'fum' );

في أبسط map يعمل مثل شكل متخصص من أ for عقدة. تنتج قطعتان من الكود نفس النتيجة بالضبط:

my @foo = map {$_ * 2} 1..5;

my @bar;
for (1..5) {
     my $val = $_ * 2;
     push @bar, $val;
}

آمل أن يكون هذا قد أعطاك بعض المساعدة في تعلم كيفية التفكير فيه map. بمجرد أن تتعلم استخدامه (والبنيات ذات الصلة مثل grep و apply) سوف تكون قادرًا على التعبير عن الأفكار التي يمكن أن تُفبر بشكل لا يصدق عند بناؤها باستخدام رمز الحلقات العادية.

نصائح أخرى

$return_name = map { $return_name = $return_name . $query->param($_) . $separator } @vals;

هذه مهمة قياسية ، والتي تعطي سياق تشغيل تشغيل الخريطة.خريطة في سياق العددية ، يعيد عدد العناصر التي كان من الممكن إنتاجها.

بينما يصرخ هذا السطر الخاص من التعليمات البرمجية لاستخدام انضم(), ، إذا أتيت من خلفية البرمجة الوظيفية ، فقد تكون أكثر راحة مع الحد من:

use List::Util 'reduce';
$return_name = reduce { $a . $query->param($b) . $separator } "", @vals;

map إرجاع قائمة ، وليس سلسلة. جرب هذا:

$return_name = join $separator, map { $query->param($_) } @vals;

أو إذا كنت تريد حقًا قطع عدد الخطوط ، فحاول:

my $return_name = join ':', 
    map { $query->param($_) } 
    qw(name last-name first-name phone);

(كانت النسخة ذات السطر الواحد مستوحى من إجابة DSM.)

جرب هذا:

join $separator, 
     map { $query->param($_) } 
     ("name", "last-name", "first-name", "phone");

للإجابة على سبب حصولك على "4" ، فذلك لأنك تقوم بتعيين الأدوات الناتجة عن العلب إلى العددية.

بالإضافة إلى جميع الإجابات الجيدة التي تلقيتها ، لاحظ ذلك

$return_name = $return_name . $query->param($_) . $separator;

يمكن كتابتها باسم

$return_name .= $query->param($_) . $separator;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top