replacing the value of an element in an array without creating a new array - arrays

I'm learning Ruby and have been practicing by solving problems on Codewars and Leetcode. I've come across this problem in Leetcode where it is asking me to, given an array and a value, modify the array in place by removing an occurrence of the value given in the array. Pretty simple! I was able to solve it- but, this curious thing happened and I don't know why!
Here's my code:
def remove_element(nums, val)
nums.each_with_index do |num, index|
if num == val
nums[index] = nil
end
end
nums.compact!
nums.length
end
You can see here that on line 4 I've written "nums[index] = nil", and this worked just fine for me. However, for the longest time I was trying to solve the challenge by writing "num = nil". What doesn't make sense to me is, why does "nums[index]" work and not "num"? Don't they refer to the same thing?

Answer from Dave Newton:
num is a block-local variable, nums is the array. Modifying a local parameter is different than accessing a reference. As another example, say that the array was filled with objects. num.some_property = 5 would modify the property of the array entry, num = SomeNewObject.new would just create a new object and not modify the array entry. Same thing would happen if you were calling a function.

Related

What does &array[element] means and why?

I was coding in MPI using C. I don't understand how the MPI_Send() works or if maybe &array[element] works.
MPI_Send(&array[element],element_left,MPI_INT,i,0,MPI_COMM_WORLD);
here array[]={1,2,3,4,5,6,7,8,9,10} and element = 6 and element_left = 4. I understand array[element]=array[6]=7 but why this function picks 7,8,9,10? I know it will pick 4 elements from the array but why do we need & here and by only giving starting entry array[6] how is this function able to pick the next 3 as well?
I thought I have to add one after another using a for loop or something, but when I searched something on Google I got this code and after going through so much I still didn't understand. Please help me understand the backwardness of this code.
&array[element] is the same expression as array + element and means the address of the elementth element of the array array.
The function you call wants this address as the first argument, and takes the number of elements to process as the second argument.
Most MPI routines take a trio of arguments:
address of buffer
count of elements
datatype of elements
So by &array[element],element_left,MPI_INT you specify the elements element as the start of the buffer, and then you take element_left many integers to send. Kinda strange that you name the count element_left which is more like a name for an index, but that's what happens.

No exact matches in call to subscript, reversed array in Swift

I am trying to understand different Swift's basics better. I bumped on the reversed array concept in Paul Hudson's videos.
He said that the array will be printed in the same order as the original one, but also that other operations will be done on the reversed version of the array.
And so I did this:
let presidents = ["Bush", "Obama", "Trump", "Biden"]
let reversedPresidents = presidents.reversed()
print(reversedPresidents[2])
And I received:
No exact matches in call to subscript
error.
Why?
It's explained reversed documentation.
First of all, it returns the type ReversedCollection<Array<Element>>
Secondly, it doesn't really change the order of array, as explained here:
or ordinary collections c having bidirectional indices:
c.reversed() does not create new storage
c.reversed().map(f) maps eagerly and returns a new array
In other words: reversed() is able to iterate the provided array in reverse order, but does not create a reversed array
So if you want to create a reversed array, you can either do this:
let reversedPresidents = presidents.reversed().map { $0 }
or, as mentioned in comment above,
let reversedPresidents = Array(presidents.reversed())

initialize an array with loop in Eiffel

I'm trying so hard to initialize an array or arrayList of strings from a file while using a loop, but every function I'm using- put/enter/force nothing seems to work. the array time after time got filled with the last string I read even though I'm accessing a specific index that I increasing every iteration.
(I tried to add regular constant string and it worked well, I don't understand the difference.
Thanks to everyone who would help.
tArray:ARRAY[STRING] -- declaring
create tArray.make_empty
readingFile() --function
local
k:INTEGER_32
do
from k:=0
until curFile.end_of_file
loop
curFile.read_line
curLine:=curFile.last_string
tArray.force (curLine, k)
--tArray.put(curLine, k)
--tArray.enter (curLine, k)
--tArray.at (k):=curLine
--tArray.force ("sara", k+1)
k:=k+1
end
end
The feature read_line does not create a new string object every time, but rather reuses the last one. In other words, last_string always refers to the same object. The solution is to use a clone of the object associated with last_string at every iteration:
curLine := curFile.last_string.twin

Ruby Koans - Array population method affects how it returns

I've been working on Ruby Koans and I've gotten to this part that I don't understand too well. Specifically, it's the about_dice_project, where they ask us to define a class to pass several pre-set tests. Originally, my class looked like
class DiceSet
attr_accessor :values
def initialize
#values = []
end
def roll(num)
num.times { |i| #values[i] = rand(1..6) }
return #values
end
end
But this failed the test below
dice = DiceSet.new
dice.roll(5)
first_time = dice.values
dice.roll(5)
second_time = dice.values
assert_not_equal first_time, second_time,
"Two rolls should not be equal"
And I realized after some testing that both first_time and second_time have the same object_id. So I looked on stackoverflow for some help and found this answer, which doesn't answer my question directly, but I did find a major difference in our code; namely, that instead of using the "num.times" way of rolling the dice, goes instead with
#values = Array.new(num) { rand(1..6) }
and this does pass the above test.
After finding this, I was trying to figure out why my original code didn't work, and so I thought that maybe Ruby was passing by reference, and that's why when the dice-rolling-method created a new array instead of modifying the existing array, that was a new object id created. But then I found this question, which says that Ruby is pass-by-value, and if that was the case, then I would have expected that my original way would work.
So now I'm confused again, and I'd like to ask - where did my line of thought go wrong? Is Ruby pass-by-value only in certain cases? Have I misunderstood what pass-by-value/reference even means? Is my issue not related to pass-by-value/reference at all?
You can see object in ruby as a reference to data.
So even if Ruby is pass by value, the thing got copy is object, a.k.a a handle to underlining data.
Even from the answer you link to, had said:
Variables are always references to objects. In order to get an object that won't change out from under you, you need to dup or clone the object you're passed, thus giving an object that nobody else has a reference to. (Even this isn't bulletproof, though — both of the standard cloning methods do a shallow copy, so the instance variables of the clone still point to the same objects that the originals did. If the objects referenced by the ivars mutate, that will still show up in the copy, since it's referencing the same objects.)

Array (class) filled with non nil values stays empty

I am currently having trouble filling up an array of customClass.
I try to fill it with a jsonFile. During my json parsing (using swiftyJSON) i loop and fill my array.
The problem is, at the end of my loop, it is still empty. I tested it in different ways, and here is my code:
That's the file where the problem is. In my loop I fill an Annotation, that I add with append to my array. The problem is what my print return. Here is a part of it:
It's just a small part of a huge jsonfile. And, my tmpAnnot.name is correctly printed every iteration. But when it comes to my Array, nothing.
So I'm completly lost and hope you could help me ^^
(And for the information, here is my custom class) :
And btw, I tried to print my array.count, and it's nil too
Im so sorry if the question has been posted. I couldn't find it in the entire website.
Change your JSONAnnotationList declaration to be an non-optional and assign it an empty array
var JSONAnnotationList: [UGOAnnotation] = []
You see, you have never created an array so there was nothing to be printed.
The whole point of optionals is to use them sparingly, not everywhere.

Resources