From: Michael Neumann Date: 2001-09-02T00:44:59+09:00 Subject: [ruby-talk:20672] Re: corresponding "non-bang" method to []= Tobias Reif wrote: > Hi, Hi, > There's "collect", and the bang version "collect!" > > AFAICS, []= is bang. What's the non-bang version? There's no one. Does it make sense to have one? Not for me. You may copy the receiver before with dup or clone, like Python's does with [:] when changing an array inside a for-loop. > I'm trying to modify specific members of an array, depending on their > position in the array ("second and last get a newline" etc.). > I'm working my way through the docs, faqs, and the Pickaxe. > Now after hours of trying, I only got it to work using a dirty hack. > I'm looking for a nice way. > > So because in collect there is no index passed to the block, I need to > use each_index, where I need to use []= to set the new value. (AFAIK) > > But I don't want to modify the original, because I need to modify it > differently in another method starting from it's previous state. > > In pseudo-code: > > an_array.each_index do |x| > new_val = an_array.at(x) + "\n" > if (x == 2) or (x == (an_array.size - 1)) > an_array.set_at(x,new_val) > end > end an_array.dup.each_index do |x| ... end should do it. > or > > an_array.collect |index,item| > if (index == 2) or (index == (an_array.size - 1)) > item + "\n" > else > item > end > end How about: an_array[0..1] + [an_array[2] + "\n"] + an_array[3..-2] + [an_array[-1] + "\n"] Alternatively, you may use a counter: index = -1 an_array.collect do |item| index += 1 if (index == 2) or (index == (an_array.size - 1)) item + "\n" else item end end or otherwise create an array that contains subarrays with "index,item" as elements: an_array.collect {|i| [nil, i]}.each_with_index{|i, e| e[0] = i}.collect do |index, item| ... proceed as above end Regards, Michael -- Michael Neumann merlin.zwo InfoDesign GmbH http://www.merlin-zwo.de