Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing the values in an array of lists of pairs

Tags:

hashmap

raku

my @products = (
    (name => "samsung s6" , price => "600"),
    (name => "samsung s7" , price => "700"));

# for @products -> $x { say $x{"name"} ~ ": USD" ~ $x{"price"} };

# Desired output:
#
# samsung s6: USD600
# samsung s7: USD700

# Real output: An error:
#
# "Type List does not support associative indexing."

I would also like to iterate using the .kv method and the $key and $val like so:

for @products -> $x.kv -> $key,$val  { say $x{$key} ~ " " ~ $x{$val} };

# That gives a "Malformed parameter" error

I've looked up the Raku documentation but this particular case isn't mentioned in the documentation. How to do it? Alternative ways or improvisation on the code are welcome.

like image 576
Lars Malmsteen Avatar asked Aug 24 '20 13:08

Lars Malmsteen


People also ask

How to access entire value of an array one after another?

num1 = 23 * 9; Becaue, arr [1] refers to the value 23 and arr [3] refers to the value 9. If you are required to access entire value of an array one after another, then you can use loop constructs to iterate through array.

How to access array’s value in Java?

You can access array’s value by its index position. Each index position in array refers to a memory address in which your values are saved. If you have to access value from above array then you can access value by following ways:

How to access elements in an array?

The array is a type of data structure that can be used to store a collection of items, the collection of items can be either of the same datatype or different. The elements in an array can be accessed using the index. The index of the array usually starts at 0, so to access the first element you must use the index [0].

How to access value from above array in C++?

If you have to access value from above array then you can access value by following ways: int num1, num2; num1 = arr * arr; It is same as:


2 Answers

It's always important to make your data structures right. In this case, they don't feel right, but I guess you are forced to use that format. In any case, I would solve it like this:

for @products.map( { |(.[0].value, .[1].value) } ) -> $name, $price {

In words: map the list with pairs to a Slip (prefix |) with just the values of the pairs, and feed that into $name and $price two elements at a time. Perhaps better readable would be:

for @products.map( { (.[0].value, .[1].value).Slip } ) -> $name, $price {
like image 164
Elizabeth Mattijsen Avatar answered Oct 08 '22 02:10

Elizabeth Mattijsen


For the data given, you can use this sub-signature:

for @products -> @ ( :$name, :$price ) {
  say "$name: USD$price"
}

So this expects a single unnamed listy argument @.
It then expounds upon that by saying it contains two named values.
(This works because you have them as Pair objects.)


Really what you had was very close to working, all you had to do was coerce to a Hash.

for @products -> $x { say $x.hash{"name"} ~ ": USD" ~ $x.hash{"price"} }

for @products -> Hash() $x { say $x{"name"} ~ ": USD" ~ $x{"price"} }

Personally if I were going to do a lot of work with this data I would create an ecosystem for it.

class Product {
  has $.name;
  has $.price;

  our sub from-JSON-list ( @ (:$name, :$price) --> ::?CLASS ) {
    ::?CLASS.new( :$name, :$price )
  }

  method gist ( --> Str ) { "$.name: USD$.price" }
}


@products .= map: &Product::from-JSON-list;

.say for @products;

If you didn't like the & you could create a constant alias to the sub.

…

  constant from-JSON-list =
  our sub from-JSON-list ( @ (:$name, :$price) ) {
    ::?CLASS.new( :$name, :$price )
  }

…

@products .= map: Product::from-JSON-list;
like image 5
Brad Gilbert Avatar answered Oct 08 '22 02:10

Brad Gilbert