2012-05-02 18 views
5

Estoy construyendo un conjunto de hashes de matricesAñadiendo valor a la matriz si la condición se satisfizo

my @array = (
    {label => 'first hash'}, 
    {label => 'second hash', 
    innerarray => [ 
     {label => 'first inner hash'}, 
     {label => 'second inner hash'}, 
     ] 
    }, 
); 

¿Hay una manera de agregar sólo el segundo resumen interna sólo si una condición se satisfizo? Algo como esto:

my @array = (
    {label => 'first hash'}, 
    {label => 'second hash', 
    innerarray => [ 
     {label => 'first inner hash'}, 
     {label => 'second inner hash'} if 1==1, 
     ] 
    }, 
); 

me trató de reescribir mi código utilizando empuje:

my @innerarray =(); 
push @innerarray, {label => 'first inner hash'}; 
push @innerarray, {label => 'second inner hash'} if 1==1; 

my @array = (
    {label => 'first hash'}, 
    {label => 'second hash', 
    innerarray => \@innerarray 
    }, 
); 

Pero se hace muy ilegible, ya que tengo que definir previamente todas matriz interna antes de usarlos, que en algunos casos hay varias 100 líneas de código por encima del uso.

¿Hay alguna forma de añadir la condición si directamente donde insertar el elemento de la matriz?

Respuesta

8

Utilice la conditional operator, es utilizable como expresión.

my @array = (
    {label => 'first hash'}, 
    { 
     label  => 'second hash', 
     innerarray => [ 
      {label => 'first inner hash'}, 
      (1 == 1) 
       ? {label => 'second inner hash'} 
       :(), 
     ] 
    }, 
); 
+0

Gracias, funciona exactamente como yo lo necesitan. – Pit

+1

"operador ternario" no es su nombre, es sólo una descripción de cuántos operandos que se necesita. El operador condicional no es el único operador ternario de Perl. (por ejemplo 'dbmopen') fijo. – ikegami

6

va a guardar una referencia a un array en su innerarray (ejemplo 1), pero en su reescritura intenta almacenar la matriz.
probar este lugar:

my @innerarray =() ; 
push @innerarray, {label => 'first inner hash'}; 
push @innerarray, {label => 'second inner hash'} if 1==1; # Not a real condition ... 

my @array = (
    {label => 'first hash'}, 
    {label => 'second hash', 
    innerarray => \@innerarray 
    }, 
) ; 

Y también se les faltaban un ; dos veces.

Y para su pregunta en inlining algún contenido ...

my @array = (
    {label => 'first hash'}, 
    {label => 'second hash', 
    innerarray => [ 
     {label => 'first inner hash'}, 
     ($condition == 1 ? {label => 'second inner hash'} :()) , 
     ] 
    }, 
) ; 
+0

Tienes razón, pero no resuelve mi problema inicial :( – Pit

+0

@Pit He actualizado mi respuesta. Tener una mirada en ella. – dgw

+1

Sí, misma solución que @daxim – Pit

2

Usted puede hacer:

#!/usr/bin/env perl 

use strict; use warnings; 

my @array = (
    {label => 'first hash'}, 
    {label => 'second hash', 
    innerarray => [ 
     {label => 'first inner hash'}, 
     1 == 0 ? {label => 'second inner hash'} :(), 
     ] 
    }, 
); 

use YAML; 
print Dump \@array; 

Salida:

--- 
- label: first hash 
- innerarray: 
    - label: first inner hash 
    label: second hash

Pero, ¿por qué ?

También puede hacer:

({label => 'second inner hash'}) x (1 == 0), 

pero, de nuevo, por eso ?

En concreto, la incorporación de este en la inicialización de la estructura de datos oculta visualmente lo que está sucediendo desde el lector del código. Si las condiciones son incluso un poco complicado, que está obligado a introducir difícil de rastrear errores.

2

Además del operador condicional (y a veces en combinación con ella), map es a menudo útil en circunstancias similares.

my @labels = (
    'first inner hash', 
    'second inner hash', 
); 

my @array = (
    {label => 'first hash'}, 
    { 
     label  => 'second hash', 
     innerarray => [ 
      (map { { label => $_ } } @labels), 
     ] 
    }, 
); 
Cuestiones relacionadas