How to best modify an array using .each - arrays

I am using Ruby, and I am relearning arrays and trying to better understand them. I know what they are but have never fully utilized them. I have an array, odds, and wanted to double every number in it. I came up with the below solution; however, I wanted to see if there was a more elegant/simple solution to my problem.
odds = [1,3,5,7,9]
odds.each do |x|
odds[odds.index(x)]=x*2
end
end result is odds = [2,6,10,14,18]

You can use the map! enumerator to modify every item in an array:
odds.map!{ |x| x*2}

If you really want to modify in place, and you really want to use each, I guess your approach is as good as any. It doesn't feel idiomatic, but it does meet your stated constraints.
Here are some more common approaches:
Array.map
Mapping the array with map won't modify the original array (it's not in-place), which is often a good thing, but it might not be what you're looking for:
odds.map { |x| x*2 }
Array.map!
If you really do want to modify the original array, you can use map! to map in-place:
odds.map! { |x| x*2 }
Array.each_index
You did ask specifically about each, so if you want to use an each and you want to modify the original array, each_index might be your best bet:
odds.each_index { |i| odds[i] *= 2 }

Related

Iterating for `setindex!`

I have some specially-defined arrays in Julia which you can think of being just a composition of many arrays. For example:
type CompositeArray{T}
x::Vector{T}
y::Vector{T}
end
with an indexing scheme
getindex(c::CompositeArray,i::Int) = i <= length(c) ? c.x[i] : c.y[i-length(c.x)]
I do have one caveat: the higher indexing scheme just goes to x itself:
getindex(c::CompositeArray,i::Int...) = c.x[i...]
Now the iterator through these can easily be made as the chain of the iterator on x and then on y. This makes iterating through the values have almost no extra cost. However, can something similar be done for iteration to setindex!?
I was thinking of having a separate dispatch on CartesianIndex{2} just for indexing x vs y and the index, and building an eachindex iterator for that, similar to what CatViews.jl does. However, I'm not certain how that will interact with the i... dispatch, or whether it will be useful in this case.
In addition, will broadcasting automatically use this fast iteration scheme if it's built on eachindex?
Edits:
length(c::CompositeArray) = length(c.x) + length(c.y)
In the real case, x can be any AbstractArray (and thus has a linear index), but since only the linear indexing is used (except for that one user-facing getindex function), the problem really boils down to finding out how to do this with x a Vector.
Making X[CartesianIndex(2,1)] mean something different from X[2,1] is certainly not going to end well. And I would expect similar troubles from the fact that X[100,1] may mean something different from X[100] or if length(X) != prod(size(X)). You're free to break the rules, but you shouldn't be surprised when functions in Base and other packages expect you to follow them.
The safe way to do this would be to make eachindex(::CompositeArray) return a custom iterator over objects that you control entirely. Maybe just throw a wrapper around and forward methods to CartesianRange and CartesianIndex{2} if that data structure is helpful. Then when you get one of these custom index types, you know that SplitIndex(CartesianIndex(1,2)) is indeed intending to refer to the first element in the second array.

ruby .map! or each for modifying an array in place

I have the following:
article_results.keys do |key|
article_results[key].map! do |a|
a[:filename] = c.filename
a[:sitename] = c.site_name
a
end
end
As I want to add to each element of each array within the hash dynamically, but for some reason a[:filename] and a[:sitename] are blank when they are used.
So I want to know if I should be using .each instead.
Also I guess I'd like to know what's the main difference since they both can be used for side-effects.
I'm adding this as an extra fyi, I'm using ruby 1.8.7 so it would be nice to know how it differs between versions (1.8.7 - 1.9+) as well.
P.s. I know what the difference between .each and .map is, I'm asking specifically about .map!.
#map has a bit different semantics for hashes than it has for arrays (and i think it's not very consistent between versions of ruby). in general if you are looking for an array as a result of some operation - #map is your friend, however if you want hash as a result of some operation - you're better off with #reduce:
article_results.reduce({}) do |hash, (key, value)|
hash.merge(key => value.merge(filename: c.filename,
sitename: c.sitename))
end
alternatively if you don't care how "functional" your code is, you can use #each:
article_results.each do |key, value|
article_results[key].merge!(filename: c.filename,
sitename: c.sitename)
end

Ruby - Error accessing instance variables

I'm learning Ruby, and I'm having a problem while making a program.
I have a class "LineAnalyzer" that has 4 parameters (2 provided and 2 calculated). Both calculated params are: #high_wf_count (integer) and #high_wf_words (array).
Then, I have this one:
class Solution < LineAnalyzer
attr_reader :analyzers,
:highest_count_across_lines,
:highest_count_words_across_lines
def initialize
#analyzers = []
end
def analyze_file
File.foreach('test.txt') do |line|
#analyzers << LineAnalyzer.new(line.chomp,#analyzers.length+1)
end
end
def calculate_line_with_highest_frequency
#highest_count_words_across_lines = []
#highest_count_across_lines = #analyzers.max_by do
|a| a.instance_variable_get(:#highest_wf_count)
end .instance_variable_get(:#highest_wf_count)
#highest_count_words_across_lines << #analyzers.each do
|a| a.instance_variable_get(:#highest_wf_count) == #highest_count_across_lines
end .instance_variable_get(:#highest_wf_words)
end
end
The problem is that I cannot append the array #highest_wf_count to #highest_count_words_across_lines in the way I've done (it returns nil). But, I've previously taken the integer #highest_wf_count in the same way perfectly.
Can anyone tell me where's the problem?
Thanks in advance!
It seems that your problem is in this bit of code:
#highest_count_words_across_lines << #analyzers.each do
|a| a.instance_variable_get(:#highest_wf_count) == #highest_count_across_lines
end .instance_variable_get(:#highest_wf_words)
Preferably formatted as:
#highest_count_words_across_lines << #analyzers.each do |analyzer|
analyzer.instance_variable_get(:#highest_wf_count) == #highest_count_across_lines
end.instance_variable_get(:#highest_wf_words)
The problem here is that you are calling .instance_variable_get(:#highest_wf_words) on the result of the :each method.
A few lines above, you are doing something similar, where you call .instance_variable_get(:#highest_wf_count) on the result of the :max_by method, and it is working.
The difference between :max_by and :each is that :max_by returns a single analyzer, whereas :each returns the array of #analyzers over which it is iterating.
When you call :instance_variable_get(:#highest_wf_words) on that array, it's returning nil because an array will not have an instance variable named :#highest_wf_words
That is where your problem exists.
Sidenote:
It is generally not good practice to ever use :instance_variable_get. I would recommend adding to your analyzer class attr_reader :highest_wf_words, :highest_wf_count
Then, instead of calling analyzer.instance_variable_get(:#highest_wf_words), you can just call analyzer.highest_wf_words
There's a lot going on here and most of the code results from going against the grain when writing Ruby. Using instance_variable_get should be an absolute last resort. It's considered highly rude to just reach into an object and pull out a variable. It creates ugly and undesirable inter-dependencies. If that other object wanted to give you that value it would have a method to access it.
The way I see it what you're trying to do boils down to something like this:
def highest_frequency
#analyzers.map do |a|
a.highest_wf_count
end.sort.last
end
Let Analyzer implement highest_wf_count as a method, even if it's just an attr_reader. This gives you the flexibility to change how and when that value is computed. Maybe you don't need to do it when the object is initialized. Maybe it's done in another thread, or it's evaluated lazily.
Whenever possible try and structure your code as a series of straight-forward transformations. Try not to create convoluted, branching, ugly comparisons. Lean on Enumerable whenever possible, it's usually got a method that does exactly what you want, or two that in conjunction do the job perfectly.
This is way more complex than it needs to be (or should be).
Why does Solution subclass LineAnalyzer? And why are you using instance_variable_get? You should define getter methods using attr_reader on the LineAnalyzer class so you can call methods instead of using instance_variable_get, which is a brute force approach that should only be used as a last resort.
I think you should fix this before proceeding.
When you have instance methods created with attr_reader, calculating the max becomes very simple:
highest_count_across_lines = #analyzers.map(&:highest_wf_count).max
I think your error probably is caused by these lines:
#highest_count_words_across_lines << #analyzers.each do
|a| a.instance_variable_get(:#highest_wf_count) == #highest_count_across_lines
end .instance_variable_get(:#highest_wf_words)
I suggest simplifying this code, and the error will probably present itself to you. Did you really mean to append the value returned by each to #highest_count_words_across_lines? This will be an Array of analyzers. The Array class, of course, does not have a variable named :#highest_wf_words.
Again, I think you really need to simplify this code.

matlab: structural data and multi-level indexing

I have a simple problem with structures.
Lets create:
x(1).a(:, :) = magic(2);
x(2).a(:, :) = magic(2)*2;
x(3).a(:, :) = magic(2)*3;
how to list a(1, 1) from all x-es?
i wanted to do it like:
x(1, :).a(1,1)
but there is an error "Scalar index required for this type of multi-level indexing."
How to approach it? I know I can do it with a loop, but that's probably the worst solution :)
Thanks!
This is not the best datastructure to use if this is the sort of query you'd like to make on it, precisely because this sort of indexing cannot be done directly.
However, here is one approach that works:
cellfun(#(X) X(1,1), {x.a})
The syntax {x.a} converts x from a 'struct array' into a cell array. Then we use cellfun to apply a function as a map over the cell array. The anonymous function #(X) X(1,1) takes one argument X and returns X(1,1).
You can also get your data in this way:
B = cat(3,x.a);
out = reshape(B(1,1,:),1,[]);
By the way, loops are not evil. Sometimes they are even faster than vectorized indexation. Try it both ways, see what suits you best in terms of:
Speed - use the profiler to check
Code clarity - depends on the context. Sometimes vectorized code looks better, sometimes the opposite.

Array.isDefinedAt for n-dimensional arrays in scala

Is there an elegant way to express
val a = Array.fill(2,10) {1}
def do_to_elt(i:Int,j:Int) {
if (a.isDefinedAt(i) && a(i).isDefinedAt(j)) f(a(i)(j))
}
in scala?
I recommend that you not use arrays of arrays for 2D arrays, for three main reasons. First, it allows inconsistency: not all columns (or rows, take your pick) need to be the same size. Second, it is inefficient--you have to follow two pointers instead of one. Third, very few library functions exist that work transparently and usefully on arrays of arrays as 2D arrays.
Given these things, you should either use a library that supports 2D arrays, like scalala, or you should write your own. If you do the latter, among other things, this problem magically goes away.
So in terms of elegance: no, there isn't a way. But beyond that, the path you're starting on contains lots of inelegance; you would probably do best to step off of it quickly.
You just need to check the array at index i with isDefinedAt if it exists:
def do_to_elt(i:Int, j:Int): Unit =
if (a.isDefinedAt(i) && a(i).isDefinedAt(j)) f(a(i)(j))
EDIT: Missed that part about the elegant solution as I focused on the error in the code before your edit.
Concerning elegance: no, per se there is no way to express it in a more elegant way. Some might tell you to use the pimp-my-library-Pattern to make it look more elegant but in fact it does not in this case.
If your only use case is to execute a function with an element of a multidimensional array when the indices are valid then this code does that and you should use it. You could generalize the method by changing the signature of to take the function to apply to the element and maybe a value if the indices are invalid like this:
def do_to_elt[A](i: Int, j: Int)(f: Int => A, g: => A = ()) =
if (a.isDefinedAt(i) && a(i).isDefinedAt(j)) f(a(i)(j)) else g
but I would not change anything beyond this. This also does not look more elegant but widens your use case.
(Also: If you are working with arrays you mostly do that for performance reasons and in that case it might even be better to not use isDefinedAt but perform validity checks based on the length of the arrays.)

Resources