0

I know it is not possible to have duplicate keys in a hash, but this is what my data looks like:

Key                Value

SETUP_FACE_PROT    great
SETUP_FACE_PROT    great2
SETUP_FACE_PROT    great3
SETUP_FACE_PROT    great3
SETUP_ARM_PROT     arm
SETUP_FOOT_PROT    foot
SETUP_FOOT_PROT    foot2
SETUP_HEAD_PROT    goggle 

I would like to concatenate values for repeated keys, separated by a * character. For example, this is what I want the output to look like:

SETUP_FACE_PROT'=great*great2*great3',
SETUP_ARM_PROT='arm',
SETUP_FOOT_PROT='foot*foot2',
SETUP_HEAD_PROT='google'

This is how I've tried to solve the problem so far:

foreach my $key ( sort keys %stuff ) 
{
   print "$key=\'", join( "*", @{ $stuff{$key} } ), "\'\n";
}

But instead of printing the result, how can I store it in a variable so that I can pass it to another subroutine? I'm trying to create a new string that looks like this:

$newstring="
SETUP_FACE_PROT='great*great2*great3',
SETUP_ARM_PROT='arm',
SETUP_FOOT_PROT='foot*foot2',
SETUP_HEAD_PROT='google'  "

2 Answers 2

2

You can't duplicate keys, you can create a hash of arrays.

#!/usr/bin/env perl

use strict;
use warnings;
use Data::Dumper;

my %stuff;

while (<DATA>) {
    my ( $key, $value ) = split;
    push( @{ $stuff{$key} }, $value );
}

print Dumper \%stuff;

foreach my $key ( sort keys %stuff ) {
    print "$key=\'", join( "*", @{ $stuff{$key} } ), "\'\n";
}

__DATA__
SETUP_FACE_PROT great
SETUP_FACE_PROT great2
SETUP_FACE_PROT great3
SETUP_FACE_PROT great3
SETUP_ARM_PROT arm
SETUP_FOOT_PROT foot
SETUP_FOOT_PROT foot2
SETUP_HEAD_PROT goggle

Edit:

Turning it into a string as requested:

my $results; 
foreach my $key ( sort keys %stuff ) {
    $results .= "$key=\'". join( "*", @{ $stuff{$key} } ). "\'\n";
}

print $results;

Or perhaps using print still with a filehandle:

my $results; 
open ( my $output, '>', \$results ); 
foreach my $key ( sort keys %stuff ) {
    print {$output} "$key=\'", join( "*", @{ $stuff{$key} } ), "\'\n";
}
close ( $output );
print $results;
Sign up to request clarification or add additional context in comments.

9 Comments

But i want to return that variable instead of printing .any idea.and how to store this in variable.whole result.
Return it where? This produces the output as in your question. You don't give any more detail, so I can't answer.
agreed .actually what i was saying was instead of printing :
"$key=\'", join( "", @{ $stuff{$key} } ), "\'\n"; i wannt] to store this in variable .so that end result i will get is :SETUP_FACE_PROT = 'greatgreat2*great3',SETUP_FACE_PROT='arm',SETUP_FOOT_PROT='foot*foot2',SETUP_HEAD_PROT='google'
If you've further clarification of the desired output, then it's best edited into your question.
|
0

At last i got an answer doing this.

   use Data::Dumper;
   my %stuff;
   use Text::CSV;
   my $csv = Text::CSV_XS->new ({ binary => 1, eol => $/ });

   my $filenamex = 'duplicate2.csv';

   $checkstring ='';
    open(my $datab, '<', $filenamex) or die "Could not open '$filename' $!\n";
    $i=1;
    my %datan;
    while (my $linea = <$datab>) 
    {
      chomp $linea;
      @fieldsx = split ",",$linea;
      $key = $fieldsx[0];
      $value = $fieldsx[1];
     # print $key;
       push( @{ $stuff{$key} }, $value );
    }



 foreach my $key ( sort keys %stuff ) 
  {
   $checkstring = $checkstring.','.$key.'='. join( "*", @{ $stuff{$key} } );
  }

 print $checkstring;

2 Comments

Why do you load Text::CSV, create a Text::CSV parser object and then not use it? Also, Sobrique's answer is a much cleaner version of this code. Why not use that instead?
OK. Updated the answer to include a single variable containing the data.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.