printing out the values of a hash coming from an array - arrays

I have a hash called sales_hash that I am printing out. Each hash has a key called sku that matches a hash inside the array of array_items. I get the hash out of the array and am trying to print the values of the hash based on the key which is :item but I keep getting an error. What am I doing wrong?
sales_hash.take(10).each do |a, b|
temp_hash = array_items.select{|array_items| array_items[:sku] == a}
puts temp_hash
puts "Sku is #{a} the amount sold is #{b} the name of the book is #{temp_hash[:price]}"
end
The line #{temp_hash[:item]}" keeps giving me an error

Your temp_hash is actually an array.
From the Docs:
select -> Returns a new array containing all elements of ary for which the given block returns a true value.
And you can't access and array like this: array[:key].

Since temp_hash is an array, and you're sure that there's only one item inside that array, the proper way to get the content of temp_hash is using "first" like this:
#{temp_hash.first[:price]}

As your temp_hash is an array, so you can access the expected hash like this:
temp_hash[0] # this will give you the expected hash data
And, then you can access the required key inside the hash (e.g. price):
temp_hash[0][:price]

Related

Using .map with a nested two-dimensional array

I have a nested array, like this:
aux = [["None", ""],["Average", "avg"],["Summation", "sum"],["Maximum", "max"],["Minimum", "min"],["Count", "count"],["Distinct Count", "distinctCount"],["Max Forever", "maxForever"],["Min Forever","minForever"],["Standard Deviation","stddev"]]
Now, what i want to do, is to append "1234" (it's an example) to the beginning of the second element of each array, but not on the original array, like this:
new_aux = aux.map {|k| [k[0],k[1].prepend("1234")]}
Problem is that with this, the original array is being changed. I was reading about this and the problem seems to be the manipulation of the string, because if i convert that element to symbol, for example, the original array its not changed, like i want, but i don't exactly get what is the problem here and how should i do this.
By doing this, in new_aux i get:
[["None", "1234"],
["Average", "1234avg"],
["Summation", "1234sum"],
["Maximum", "1234max"],
["Minimum", "1234min"],
["Count", "1234count"],
["Distinct Count", "1234distinctCount"],
["Max Forever", "1234maxForever"],
["Min Forever", "1234minForever"],
["Standard Deviation", "1234stddev"]]
Which is what i want, the thing is that i have the exact same thing in the original array, which is what i don't want.
prepend mutates a string itself, so using this method you change the source array. Use strings interpolation to achieve your goal new_aux = aux.map {|k| [k[0],"1234#{k[1]}"]}

How I could replace and array element by array index in ruby?

I have an array like this I use
inputx.scan(/.*?\n/)
for create array this is a representation of my array
element 1 => [car;dog;soda]
element 2 => [bunny;pc;laptop]
element 3 => [hand;sword;shield]
this is my text file I use scan method for create array inputx.scan(/.*?\n/)
car;dog;soda
bunny;pc;laptop
hand;sword;shield
I need to replace each comma by number of array for obtain this
this is my expected output
in this output I replace ";" by "nthelementnumber;" example 1;
car1;dog1;soda
bunny2;pc2;laptop
hand3;sword3;shield
Please help me
It's a bit hard to tell what exactly your array looks like, but I'm going to take a guess:
element = ['car;dog;soda',
'bunny;pc;laptop',
'hand;sword;shield']
If that's correct, you can get the output you are looking for with something like:
element.each_index {|i| element[i] = element[i].gsub(';', "#{i+1};")}
The each_index iterator gives you each index (unsurprisingly). Then you can use each index to manipulate each value in the array.

Compare hash values with corresponding array values in Ruby

I've scripted my way into a corner where I now need to compare the values of a hash to the corresponding element in an array.
I have two "lists" of the same values, sorted in different ways, and they should be identical. The interesting part is when they don't, so I need to identify those cases. So basically I need to check whether the first value of the first key-value pair in the hash is identical to the first element of the array, and likewise the second value checked towards the second element and so on for the entire set of values in the hash.
I'm sort of new to Ruby scripting, but though this should be easy enough, but alas....
Sounds like all you need is something simple like:
hash.keys == array
The keys should come out in the same order as they are in the Hash so this is comparing the first key of the hash with the first element of the array, the second key with the second array element, ...
You could also transliterate what you're saying into Ruby like this:
hash.each_with_index.all? { |(k, _), i| k == array[i] }
Or you could say:
hash.zip(array).all? { |(k, _), e| k == e }
The zip version is pretty much the each_with_index version with the array indexing essentially folded into the zip.
Technically speaking, hash is not guaranteed to ordered, so your assumption of matching the value at 'each' index of hash may not always hold true. However, for sake of answering your question, assuming h is your hash, and a is your array:
list_matches = true
h.values.each_with_index {|v, i| list_matches = list_matches && a[i] == v}
if list_matches is not equal to true than that is where the the items in the two collections don't match.

Perl - Assign an array to another variable

I'm trying to assign an array to a value in my hash as follows:
$authors->[$x]->{'books'} = #books;
$authors is an array of hashes that contains his/her first name, last name, date of birth, etc. And now I'm creating a books key where I want to assign an array of books. However, when I try to print it afterwords, it's just printing the size of the array, as if I'm doing $value = scalar #books.
What am I doing wrong?
Array elements and hash values are scalars, so when you are nesting arrays and hashes, you must use references. Just as $authors->[$x] is not a hash but a reference to a hash, you must set $authors->[$x]->{'books'} to a reference to the array.
$authors->[$x]->{'books'} = \#books; # reference the original array
$authors->[$x]->{'books'} = [#books]; # reference a copy
You would then access elements of the array using something like
$authors->[$x]->{'books'}->[0]
which can be abbreviated
$authors->[$x]{books}[0]
or access the whole array as
#{$authors->[$x]{books}}
Your original attempt
$authors->[$x]->{'books'} = #books;
is exactly equivalent to
$authors->[$x]->{'books'} = scalar #books;
because the left operand of the = operator is a hash value, which is a scalar, so the right operand is evaluated in scalar context to provide something that can be assigned there.
P.S.
On rereading this answer I realized it may be confusing to say "a hash value is a scalar" because of the possible interpretation of "hash value" as meaning "the value of a hash variable" i.e. "the whole hash". What I mean when I write "hash value" is an item that is stored in a hash as a value (as opposed to a key).
While the first awnser is absolutely right,
as an alternative, you could also fo this:
push #{$authors->[$x]->{'books'}}, #books;
Then $authors->[$x]->{'books'} will be an Array that contains a copy of all
the elements from #books.
This might be more "foolproof" then working with references, as
mentioned above.

Why "array.length" returns array object when we put it inside array[]?

rand(array.length) # returns random index <br>
array[rand(array.length)] # returns random array object
I can't understand the logic behind. I would assume that second example also returns random index and then store it in array.
kitty = [100,102,104,105]
rand(kitty.length) # returns index, for example 3 ( or 0,1,2 )
array[rand(kitty.length)] # returns random array object, for example 104 ( or 100,102,105)
While array.sample would be the best way to get a random element from an array, I believe OP is asking how the chaining of methods works.
When you call: rand(array.length) a number is returned, true. However in the case of:
array[ rand(array.length) ]
a number is returned but then fed immediately into the array call, which gives you the object at that array index.
Is this a tutorial? If so, don trust it. array.sample is how to do it.
ruby code
kitty = [100,102,104,105]
kitty.sample #to get random array elements
The behavior you are describing is expected:
array[index] is a reference to an object in the provided array where index is a numeric value that is less than array.length since rand(array.length) returns a random numeric value less than array.length you are effectively accessing an element at a random index of the given array.
The same behavior can be obtained with array.sample though and is recommended.
For more information on Ruby's arrays please see the documentation at: http://ruby-doc.org/core-2.2.0/Array.html

Resources