Storing values obtained from for each loop Scala - arrays

Scala beginner who is trying to store values obtains in a Scala foreach loop but failing miserably.
The basic foreach loop looks like this currently:
order.orderList.foreach((x: OrderRef) => {
val references = x.ref}))
When run this foreach loop will execute twice and return a reference each time. I'm trying to capture the reference value it returns on each run (so two references in either a list or array form so I can access these values later)
I'm really confused about how to go about doing this...
I attempted to retrieve and store the values as an array but when ran, the array list doesn't seem to hold any values.
This was my attempt:
val newArray = Array(order.orderList.foreach((x: OrderRef) => {
val references = x.ref
}))
println(newArray)
Any advice would be much appreciated. If there is a better way to achieve this, please share. Thanks

Use map instead of foreach
order.orderList.map((x: OrderRef) => {x.ref}))
Also val references = x.ref doesn't return anything. It create new local variable and assign value to it.

Agree with answer 1, and I believe the reason is below:
Return of 'foreach' or 'for' should be 'Unit', and 'map' is an with an changed type result like example below:
def map[B](f: (A) ⇒ B): Array[B]
Compare To for and foreach, the prototype should be like this
def foreach(f: (A) ⇒ Unit): Unit
So If you wanna to get an changed data which is maped from your source data, considering more about functions like map, flatMap, and these functions will traverse all datas like for and foreach(except with yield), but with return values.

Related

Is it possible to use the range function in Azure Data Factory and add ID's to the result?

Let's say I want to use the range function (inside a ForEach loop) in Azure Data Factory to create an array which consists of integers. These integers represent API pages related to some ID which was given to us as a parameter in the ForEach loop.
I would use it like #range(1, int(varMaxApiPages)).
This gives me what I expect; an array of integers:
[1, 2, 3]
But would it be possible to append the related ID to these integers? So the result would be something like: [{"someID", 1},{"someID", 2},{"someID", 3}]?
Such as:
def appendToArray(varMaxApiPages):
arr1 = list(range(varMaxApiPages))
json_array = [];
for item in arr1:
jsonObejct = {"someID",item}
json_array.append(jsonObejct)
for item in json_array:
print(item)
appendToArray(3)
The correct json array should look like this [{"someID": 1},{"someID": 2},{"someID": 3}], we can achieve that. If you don’t want the colon, you can think of a way to replace it.
My debug result is as follows:
I declared 3 array type variables. Variable res is used to review the debug result.
In Set variable1 activity, assign the value to it via #range(1,3).
Then Foreach the arr1.
Inside Foreach activity, we can use Append variable activity, add expression #json(concat('{"someID":',item(),'}')). It will convert json string to json Object and append to the array jsonArray.
Outside Foreach activity, assign the value of array jsonArray to array res to review the result, you can omit this step and use array jsonArray directly.
That's all.

Passing Ruby array elements to a method

I'm not a programmer, but I find myself writing some simple ruby and aren't sure about a few things.
I have the following function
def resolve_name(ns_name)
ip = Resolv.getaddress(ns_name)
return ip
end
and the array
array = ['ns-1.me.com', 'ns-2.me.com']
What I want to do is to pass every element in the array to the function to be evaluated, and spit out to... something. Probably a variable. Once I have the resolved IPs I'll be passing them to an erb template. Not quite sure yet how to handle when there may be 1 to 4 possible results either.
What I want think I need to do is do an each.do and typecast to string into my function, but I haven't been able to figure out how to actually do that or phrase my problem properly for google to tell me.
http://ruby-doc.org/core-2.0.0/doc/syntax/calling_methods_rdoc.html#label-Array+to+Arguments+Conversion Doesn't quite have what I'm looking for.
irb(main):010:0> resolved = resolve_name(array)
TypeError: no implicit conversion of Array into String
Any suggestions?
Take a look at the documentation for ruby's Enumerable, which arrays implement. What you're looking for is the map method, which takes each element of an enumerable (i.e. an array) and passes it to a block, returning a new array with the results of the blocks. Like this:
array.map{|element| resolve_name(element) }
As an aside, in your method, you do not need to use a local variable if all you're doing with it is returning its value; and the return statement is optional - ruby methods always return the result of the last executed statement. So your method could be shortened to this:
def resolve_name(ns_name)
Resolv.getaddress(ns_name)
end
and then you really all it's doing is wrapping a method call in another. So ultimately, you can just do this (with array renamed to ns_names to make it self-explanatory):
ns_names = ['ns-1.me.com', 'ns-2.me.com']
ip_addresses = ns_names.map{|name| Resolv.getaddress(name) }
Now ip_addresses is an array of IP addresses that you can use in your template.
If you pass an array you could do:
def resolve_name(ns_name)
res = []
ns_name.each do |n|
res << {name: n, ip: Resolv.getaddress(name) }
end
res
end
And get an array of hashes so you know which address has which ip

can't convert Enumerator into Array

While working on one application I am getting this error:
can't convert Enumerator into Array
Here is my code, mr_collection is MongoID query.
mr_collection = self.where(query).map_reduce(map, reduce).finalize(finalize).out({:replace => 'mr_results'})
paginator = WillPaginate::Collection.new(page, limit, collection_count)
collection = mr_collection.find(
:sort => sort,
:limit => limit,
:skip => skip
)
paginator.replace(collection)
While getting mr_collection, if I inspect the result mr_collection gives me:
[
{"_id"=>1.0, "value"=>{"s"=>4.2, "p"=>14.95, "pml"=>0.01993}},
{"_id"=>2.0, "value"=>{"s"=>3.7, "p"=>12.9, "pml"=>0.0172}},
{"_id"=>3.0, "value"=>{"s"=>4.2, "p"=>12.9, "pml"=>0.0172}},
{"_id"=>4.0, "value"=>{"s"=>4.0, "p"=>11.95, "pml"=>0.01593}},
{"_id"=>300.0, "value"=>{"s"=>0.0, "p"=>8.95, "pml"=>0.01193}},
]
While getting collection, if I inspect the result collection gives me:
#<Enumerator: []:find({:sort=>[["value.s", :desc], ["value.pml", :asc]], :limit=>10, :skip=>0})>
I am getting error on the line paginator.replace(collection). I'm using Ruby 1.9.3 & Rails 3.2.6.
collection is an Enumerator which obviously can't convert into an Array, which is what replace expects.
Here are the comments from the rubydocs:
Enumerable#find(ifnone = nil) { |e| ... }
Passes each entry in enum to block. Returns the first for which block
is not false. If no object matches, calls ifnone and returns its
result when it is specified, or returns nil otherwise.
If no block is given, an enumerator is returned instead.
Therefore you have two options:
If you want all elements, yield from the Enumerator to an Array.
If you only want the first match, supply a block that determines what the match is.
Hope this helps.
(Moral of the story: always read the docs!)
I have no idea about mongoid having never used it.
But a search has brought to fore an awfully similar question -
Mongoid 3 - access map_reduce results
Unfortunately my environent is not set to test the magic of
collection = mr_collection.send(:documents).sort(sort).limit(limit).skip(skip).to_a
Have you had a look at this link? Hopefully it'll help solve your issue!

Mapping first 3 records in database to variables

I have a test spec where I use the following line of code to assign 3 variables to session tokens within my table:
#auth_token, #auth2_token, #auth3_token = Session.limit(3).map(&:token)
I now wish to assign 3 variables as a role classes from my Roles table which isn't restricted to one attribute only but the whole class. I have tried the following but it doesnt seem to be working:
#role1, #role2, #role3 = Role.limit(3).map
Can this be achieved? Any pointers would be greatly appreciated !!
It works for the auth tokens because map converts the relation object into an array which then gets assigned to the variables. For the roles just calling map returns an enumerable and not an array.
You can just call to_a directly on the relation object returned by the limit call in order to convert it to an array.
#role1, #role2, #role3 = Role.limit(3).to_a
Wasn't sure how to go about this but got round the problem using the following:
#role1 = Role.find_by_name!("First")
#role2 = Role.find_by_name!("Second")
#role3 = Role.find_by_name!("Third")

Perl -- DBI selectall_arrayref when querying getting Not Hash Reference

I am very new to perl (but from a c# background) and I am trying to move some scripts to a windows box.
Due to some modules not working easily with windows I have changed the way it connects to the DB.
I have an sqlserver DB and I had a loop reading each row in a table, and then within this loop another query was sent to select different info.
I was the error where two statements can't be executed at once within the same connection.
As my connection object is global I couldn't see an easy way round this, so decided to store the first set of data in an array using:
my $query = shift;
my $aryref = $dbh->selectall_arrayref($query) || die "Could not select to array\n";
return($aryref);
(this is in a module file that is called)
I then do a foreach loop (where #$s_study is the $aryref returned above)
foreach my $r_study ( #$s_study ) {
~~~
my $surveyId=$r_study->{surveyid}; <-------error this line
~~~~
};
When I run this I get an error "Not a hash reference". I don't understand?!
Can anyone help!
Bex
You need to provide the { Slice => {} } parameter to selectall_arrayref if you want each row to be stored as a hash:
my $aryref = $dbh->selectall_arrayref($query, { Slice => {} });
By default, it returns a reference to an array containing a reference to an array for each row of data fetched.
$r_study->{surveyid} is a hashref
$r_study->[0] is an arrayref
this is your error.
You should use the second one
If you have a problem with a method, then a good first step is to read the documentation for that method. Here's a link to the documentation for selectall_arrayref. It says:
This utility method combines
"prepare", "execute" and
"fetchall_arrayref" into a single
call. It returns a reference to an
array containing a reference to an
array (or hash, see below) for each
row of data fetched.
So the default behaviour is to return a reference to an array which contains an array reference for each row. That explains your error. You're getting an array reference and you're trying to treat it as a hash reference. I'm not sure that the error could be much clearer.
There is, however, that interesting bit where it says "or hash, see below". Reading on, we find:
You may often want to fetch an array
of rows where each row is stored as a
hash. That can be done simple using:
my $emps = $dbh->selectall_arrayref(
"SELECT ename FROM emp ORDER BY ename",
{ Slice => {} }
);
foreach my $emp ( #$emps ) {
print "Employee: $emp->{ename}\n";
}
So you have two options. Either switch your code to use an array ref rather than a hash ref. Or add the "{ Slice => {} }" option to the call, which will return a hash ref.
The documentation is clear. It's well worth reading it.
When you encounter something like "Not a hash reference" or "Not an array reference" or similar you can always take Data::Dumper to just dump out your variable and you will quickly see what data you are dealing with: arrays of arrayrefs, hashes of something etc.
And concerning reading the data, this { Slice => {} } is most valuable addition.

Resources