Zwei Arrays mischen

Zwei Arrays mischen

am 07.09.2007 14:21:18 von df4or

Tag.

Ich bin offensichtlich blockiert und komme nicht darauf wie man zwei
gleichlange Arrays (Keys, Values) möglichst elegant zu einem Array (k1,v2,
k2,v2...) mischen kann, um es z.B. in einen Hash zu verwenden.

Derzeit mache ich es mit einer foreach-Schleife, suche aber nach einer
einfacheren Lösung.

my @keys = ('k1','k2','k3');
my @vals = ('v1','v2','v3');
my @res = ();
foreach my $item (@keys) {
push @res, $item;
push @res, shift(@vals);
};

Wie ginge es einfacher/eleganter?

Danke,
Ekki

Re: Zwei Arrays mischen

am 07.09.2007 14:27:23 von Frank Seitz

Ekki Plicht (DF4OR) wrote:

> Wie ginge es einfacher/eleganter?

Für einen Hash %res geht es so am kürzesten:

@res{@keys} = @vals;

Für ein Array @res kenne ich keine Abkürzung.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Zwei Arrays mischen

am 07.09.2007 15:09:56 von Bjoern Hoehrmann

* Ekki Plicht (DF4OR) wrote in de.comp.lang.perl.misc:
>Ich bin offensichtlich blockiert und komme nicht darauf wie man zwei
>gleichlange Arrays (Keys, Values) möglichst elegant zu einem Array (k1,v2,
>k2,v2...) mischen kann, um es z.B. in einen Hash zu verwenden.

Wenn du Duplikate hast, List::MoreUtils zip/mesh Funktion macht
genau das. Ansonsten bist du mit Franks Methode gut beraten.
--
Björn Höhrmann · mailto:bjoern@hoehrmann.de · http://bjoern.hoehrmann.de
Weinh. Str. 22 · Telefon: +49(0)621/4309674 · http://www.bjoernsworld.de
68309 Mannheim · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/

Re: Zwei Arrays mischen

am 07.09.2007 15:16:26 von df4or

Frank Seitz wrote:

> Ekki Plicht (DF4OR) wrote:
>
>> Wie ginge es einfacher/eleganter?
>
> Für einen Hash %res geht es so am kürzesten:
>
> @res{@keys} = @vals;

Argh... Ok. Danke.


> Für ein Array @res kenne ich keine Abkürzung.

Danke,
Ekki

Re: Zwei Arrays mischen

am 07.09.2007 15:17:29 von df4or

Bjoern Hoehrmann wrote:

> * Ekki Plicht (DF4OR) wrote in de.comp.lang.perl.misc:
>>Ich bin offensichtlich blockiert und komme nicht darauf wie man zwei
>>gleichlange Arrays (Keys, Values) möglichst elegant zu einem Array (k1,v2,
>>k2,v2...) mischen kann, um es z.B. in einen Hash zu verwenden.
>
> Wenn du Duplikate hast, List::MoreUtils zip/mesh Funktion macht
> genau das. Ansonsten bist du mit Franks Methode gut beraten.

Nee, keine Duplikate. Ok, ich werds erstmal in nem Hash weiterverwenden, das
ist eh naheliegender. Danke.

Ekki

Re: Zwei Arrays mischen

am 09.09.2007 08:43:28 von Christian Winter

Ekki Plicht (DF4OR) schrieb:
> Tag.
>
> Ich bin offensichtlich blockiert und komme nicht darauf wie man zwei
> gleichlange Arrays (Keys, Values) möglichst elegant zu einem Array (k1,v2,
> k2,v2...) mischen kann, um es z.B. in einen Hash zu verwenden.
>
> Derzeit mache ich es mit einer foreach-Schleife, suche aber nach einer
> einfacheren Lösung.
>
> my @keys = ('k1','k2','k3');
> my @vals = ('v1','v2','v3');
> my @res = ();
> foreach my $item (@keys) {
> push @res, $item;
> push @res, shift(@vals);
> };
>
> Wie ginge es einfacher/eleganter?

Wenn Du keinen Hash brauchst und weisst, dass die Arrays
gleich lang sind:

my @res = map { $keys[$_], $vals[$_] } 0 .. $#keys;

-Christian

Re: Zwei Arrays mischen

am 09.09.2007 12:26:13 von df4or

Christian Winter wrote:

> Ekki Plicht (DF4OR) schrieb:
>> Tag.
>>
>> Ich bin offensichtlich blockiert und komme nicht darauf wie man zwei
>> gleichlange Arrays (Keys, Values) möglichst elegant zu einem Array
>> (k1,v2, k2,v2...) mischen kann, um es z.B. in einen Hash zu verwenden.
>>
>> Derzeit mache ich es mit einer foreach-Schleife, suche aber nach einer
>> einfacheren Lösung.
>>
>> my @keys = ('k1','k2','k3');
>> my @vals = ('v1','v2','v3');
>> my @res = ();
>> foreach my $item (@keys) {
>> push @res, $item;
>> push @res, shift(@vals);
>> };
>>
>> Wie ginge es einfacher/eleganter?
>
> Wenn Du keinen Hash brauchst und weisst, dass die Arrays
> gleich lang sind:
>
> my @res = map { $keys[$_], $vals[$_] } 0 .. $#keys;


Ok, danke, ich werde das gleich mal ausprobieren. Aber müssten da:

my @res = map { $keys[$_], $vals[$_] } 0 .. $#keys;
^ ^
nicht noch Klammern drum? Welchen Wert liefert denn der map Block zurück?
Doch nur den zuletzt evaluierten, ohne (), oder? Na egal, ich werds mal
testen.

Danke,
Ekki

Re: Zwei Arrays mischen

am 09.09.2007 13:17:37 von Christian Winter

Ekki Plicht (DF4OR) schrieb:
> Christian Winter wrote:
>
>> Ekki Plicht (DF4OR) schrieb:
>>> Tag.
>>>
>>> Ich bin offensichtlich blockiert und komme nicht darauf wie man zwei
>>> gleichlange Arrays (Keys, Values) möglichst elegant zu einem Array
>>> (k1,v2, k2,v2...) mischen kann, um es z.B. in einen Hash zu verwenden.
>>>
>>> Derzeit mache ich es mit einer foreach-Schleife, suche aber nach einer
>>> einfacheren Lösung.
>>>
>>> my @keys = ('k1','k2','k3');
>>> my @vals = ('v1','v2','v3');
>>> my @res = ();
>>> foreach my $item (@keys) {
>>> push @res, $item;
>>> push @res, shift(@vals);
>>> };
>>>
>>> Wie ginge es einfacher/eleganter?
>> Wenn Du keinen Hash brauchst und weisst, dass die Arrays
>> gleich lang sind:
>>
>> my @res = map { $keys[$_], $vals[$_] } 0 .. $#keys;
>
>
> Ok, danke, ich werde das gleich mal ausprobieren. Aber müssten da:
>
> my @res = map { $keys[$_], $vals[$_] } 0 .. $#keys;
> ^ ^
> nicht noch Klammern drum? Welchen Wert liefert denn der map Block zurück?
> Doch nur den zuletzt evaluierten, ohne (), oder?

Siehe "perldoc -f map":
map BLOCK LIST
map EXPR,LIST
... Evaluates BLOCK or EXPR in list context, so each element of
LIST may produce zero, one, or more elements in the returned value.

-Christian

Re: Zwei Arrays mischen

am 09.09.2007 15:26:06 von df4or

Christian Winter wrote:

> Ekki Plicht (DF4OR) schrieb:
>> Christian Winter wrote:
>>
>>> Ekki Plicht (DF4OR) schrieb:
>>>> Tag.
>>>>
>>>> Ich bin offensichtlich blockiert und komme nicht darauf wie man zwei
>>>> gleichlange Arrays (Keys, Values) möglichst elegant zu einem Array
>>>> (k1,v2, k2,v2...) mischen kann, um es z.B. in einen Hash zu verwenden.
>>>>
>>>> Derzeit mache ich es mit einer foreach-Schleife, suche aber nach einer
>>>> einfacheren Lösung.
>>>>
>>>> my @keys = ('k1','k2','k3');
>>>> my @vals = ('v1','v2','v3');
>>>> my @res = ();
>>>> foreach my $item (@keys) {
>>>> push @res, $item;
>>>> push @res, shift(@vals);
>>>> };
>>>>
>>>> Wie ginge es einfacher/eleganter?
>>> Wenn Du keinen Hash brauchst und weisst, dass die Arrays
>>> gleich lang sind:
>>>
>>> my @res = map { $keys[$_], $vals[$_] } 0 .. $#keys;
>>
>>
>> Ok, danke, ich werde das gleich mal ausprobieren. Aber müssten da:
>>
>> my @res = map { $keys[$_], $vals[$_] } 0 .. $#keys;
>> ^ ^
>> nicht noch Klammern drum? Welchen Wert liefert denn der map Block zurück?
> > Doch nur den zuletzt evaluierten, ohne (), oder?
>
> Siehe "perldoc -f map":
> map BLOCK LIST
> map EXPR,LIST
> ... Evaluates BLOCK or EXPR in list context, so each element of
> LIST may produce zero, one, or more elements in the returned value.

Ok, danke.

Ekki

Re: Zwei Arrays mischen

am 10.09.2007 07:17:25 von David Haller

On Fri, 07 Sep 2007 14:21:18 +0200, "Ekki Plicht (DF4OR)" wrote:
> Ich bin offensichtlich blockiert und komme nicht darauf wie man zwei
> gleichlange Arrays (Keys, Values) möglichst elegant zu einem Array (k1,v2,
> k2,v2...) mischen kann, um es z.B. in einen Hash zu verwenden.
>
> Derzeit mache ich es mit einer foreach-Schleife, suche aber nach einer
> einfacheren Lösung.
[..]
> Wie ginge es einfacher/eleganter?

Der Vollständigkeit halber sei neben den schon genannten Lösungen
noch List::MoreUtils' "pairwise" erwähnt:

pairwise BLOCK ARRAY1 ARRAY2
Evaluates BLOCK for each pair of elements in ARRAY1
and ARRAY2 and returns a new list consisting of
BLOCK's return values. The two elements are set to $a
and $b. Note that those two are aliases to the origi­
nal value so changing them will modify the input
arrays.
[..]
# mesh with pairwise
@a = qw/a b c/;
@b = qw/1 2 3/;
@x = pairwise { ($a, $b) } @a, @b; # returns a, 1, b, 2, c, 3

Wobei das Beispiel genau deiner Anforderung entspricht (und als Hash
uminterpretiert auch passt).

Die "pure-Perl"-(fallback)-Implementation ist via 'map' und entspricht
praktisch den bisherigen Vorschlägen hier. Allerdings, aus der Doku:

==== perldoc List::MoreUtils ====
All of the below functions are implementable in only a
couple of lines of Perl code. Using the functions from
this module however should give slightly better perfor­
mance as everything is implemented in C. The pure-Perl
implementation of these functions only serves as a fall­
back in case the C portions of this module couldn't be
compiled on this machine.
====

HTH,
-dnh, is scho wieder Zeit für ein paar Benchmarks?

--
Wer News über ein Webinterface liest, filmt auch die
Tageszeitung, um sie auf dem Fernseher anzuschauen.
(Henning Schlottmann)

Re: Zwei Arrays mischen

am 10.09.2007 22:29:49 von df4or

David Haller wrote:

> On Fri, 07 Sep 2007 14:21:18 +0200, "Ekki Plicht (DF4OR)"
> wrote:
>> Ich bin offensichtlich blockiert und komme nicht darauf wie man zwei
>> gleichlange Arrays (Keys, Values) möglichst elegant zu einem Array
>> (k1,v2, k2,v2...) mischen kann, um es z.B. in einen Hash zu verwenden.
>>
>> Derzeit mache ich es mit einer foreach-Schleife, suche aber nach einer
>> einfacheren Lösung.
> [..]
>> Wie ginge es einfacher/eleganter?
>
> Der Vollständigkeit halber sei neben den schon genannten Lösungen
> noch List::MoreUtils' "pairwise" erwähnt:

[...]
Ok, danke, interessant.

> Die "pure-Perl"-(fallback)-Implementation ist via 'map' und entspricht
> praktisch den bisherigen Vorschlägen hier. Allerdings, aus der Doku:
[über alternative Möglichkeiten mit pure Perl]

Das ist mir ziemlich wichtig. Ich verwende in dem Programm zwar schon ein
Nicht-Standard Modul, will es aber nach Möglichkeit dabei belassen.

Danke,
Ekki