1

I thought I could do it the way that has been stated below. However when I sort it this way the output is the values in hexadecimal values, instead of the string pointing to "item" in the array @menu. What I want to achieve is to sort it by "item-name"

my @menu = (
        { item => "Blazer", price => 100, color => "Brown" },
        { item => "Jeans",  price => 50, color => "Blue" },
        { item => "Shawl",  price => 30, color => "Red" },
        { item => "Suit",   price => 40, color => "Black" },
        { item => "Top",    price => 25, color => "White" },
    );    

    my @test = sort {item } @menu;

    foreach (@test){
    print $_;

    }
1
  • Did you try perldoc -f sort first? Commented Aug 1, 2023 at 8:33

4 Answers 4

3

Your print $_ prints the string value of each hash reference, so you will get something like HASH(0x1d33524). You need to print the fields of each hash that you're interested in.

Also, you need a proper comparison expression inside the sort block. Just giving the name of a hash key won't do anything useful.

use strict;
use warnings;

my @menu = (
  { item => 'Blazer', price => 100, color => 'Brown' },
  { item => 'Jeans',  price => 50,  color => 'Blue' },
  { item => 'Shawl',  price => 30,  color => 'Red' },
  { item => 'Suit',   price => 40,  color => 'Black' },
  { item => 'Top',    price => 25,  color => 'White' },
);

my @test = sort { $a->{item} cmp $b->{item} } @menu;

for ( @test ) {
  print "@{$_}{qw/ item price color /}\n";
}

output

Blazer 100 Brown
Jeans 50 Blue
Shawl 30 Red
Suit 40 Black
Top 25 White

Update

If all you want is a sorted list of the item field values then you can write this more simply

use strict;
use warnings;

my @menu = (
  { item => 'Blazer', price => 100, color => 'Brown' },
  { item => 'Jeans',  price => 50,  color => 'Blue' },
  { item => 'Shawl',  price => 30,  color => 'Red' },
  { item => 'Suit',   price => 40,  color => 'Black' },
  { item => 'Top',    price => 25,  color => 'White' },
);

my @test = sort map { $_->{item} } @menu;

print "$_\n" for @test;

output

Blazer
Jeans
Shawl
Suit
Top
Sign up to request clarification or add additional context in comments.

Comments

1

The contents of the curlies needs to be an expression that returns the whether the element $a should appear before the element $b in the final result. See perldoc -f sortfor details.

As the elements are hash references, and you want to sort on the string value of key item in those, you need to load that value for comparing

sort { $a->{item} cmp $b->{item} }

Comments

0

The first argument to sort BLOCK LIST is the block that compares two members of the list, not the way how to extract the things to compare. See sort.

my @test = sort { $a->{item} cmp $b->{item} } @menu;

Sort::Key allows you to specify "what to sort by", not "how to compare elements".

use Sort::Key qw{ keysort };
# ...
my @test = keysort { $_->{item} } @menu;

In your code without strict, the string "item" is used to compare the elements, which doesn't really change the order in any way. What you see in the output is the representation of the members of the array, i.e. hash references. If you want to see the items only, use

for (@test) {
    print $_->{item}, "\n";
}

Comments

0

See also List::UtilsBy:

use List::UtilsBy 'sort_by';

my @test = sort_by { $_->{item} } @menu;

Comments

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.