Duplicating a Ruby Array of Strings

Duplicating a Ruby array of strings

Your second solution can be shortened to arr2 = arr.map do |e| e.dup end (unless you actually need the behaviour of clone, it's recommended to use dup instead).

Other than that your two solutions are basically the standard solutions to perform a deep copy (though the second version is only one-level deep (i.e. if you use it on an array of arrays of strings, you can still mutate the strings)). There isn't really a nicer way.

Edit: Here's a recursive deep_dup method that works with arbitrarily nested arrays:

class Array
def deep_dup
map {|x| x.deep_dup}
end
end

class Object
def deep_dup
dup
end
end

class Numeric
# We need this because number.dup throws an exception
# We also need the same definition for Symbol, TrueClass and FalseClass
def deep_dup
self
end
end

You might also want to define deep_dup for other containers (like Hash), otherwise you'll still get a shallow copy for those.

Ruby method that takes a string and returns an array of duplicates capitalizing the next letter in the string in each duplicate (like a wave)

I would do this:

def wave(word)
words = Array.new(word.size) { word.dup }
words.map.with_index { |e, i| e[i] = e[i].upcase; e } - [word]
end

wave("hello")
#=> ["Hello", "hEllo", "heLlo", "helLo", "hellO"]

wave("two words")
#=> ["Two words", "tWo words", "twO words", "two Words", "two wOrds", "two woRds", "two worDs", "two wordS"]

Cloning an array with its content

You need to do a deep copy of your array.

Here is the way to do it

Marshal.load(Marshal.dump(a))

This is because you are cloning the array but not the elements inside. So the array object is different but the elements it contains are the same instances. You could, for example, also do a.each{|e| b << e.dup} for your case

ruby array of arrays get duplicate string array

Just count all sites with each_with_object:

array.each_with_object(Hash.new(0)) {|(site, count), memo| memo[site] += count}
#=> {"twitter.com"=>64, "google.com"=>25,
# "paypal.me"=>11, "yahoo.com"=>12, "youtube.com"=>31}

You can simply convert the result to array by adding to_a, but IMO hash is enough for your issue.

Use [].replace to make a copy of an array

This is the tricky concept of mutability in ruby. In terms of core objects, this usually comes up with arrays and hashes. Strings are mutable as well, but this can be disabled with a flag at the top of the script. See What does the comment "frozen_string_literal: true" do?.

In this case, you can call dup, deep_dup, clone easily to the same effect as replace:

['some', 'array'].dup
['some', 'array'].deep_dup
['some', 'array'].clone
Marshal.load Marshal::dump(['some', 'array'])

In terms of differences, dup and clone are the same except for some nuanced details - see What's the difference between Ruby's dup and clone methods?

The difference between these and deep_dup is that deep_dup works recursively. For example if you dup a nested array, the inner array will not be cloned:

  a = [[1]]
b = a.clone
b[0][0] = 2
a # => [[2]]

The same thing happens with hashes.

Marshal.load Marshal::dump <object> is a general approach to deep cloning objects, which, unlike deep_dup, is in ruby core. Marshal::dump returns a string so it can be handy in serializing objects to file.

If you want to avoid unexpected errors like this, keep a mental index of which methods have side-effects and only call those when it makes sense to. An explanation point at the end of a method name indicates that it has side effects, but others include unshift, push, concat, delete, and pop. A big part of fuctional programming is avoiding side effects. You can see https://www.sitepoint.com/functional-programming-techniques-with-ruby-part-i/

Find a Duplicate in an array Ruby

Array#difference comes to the rescue yet again. (I confess that @user123's answer is more straightforward, unless you pretend that Array#difference is already a built-in method. Array#difference is probably the more efficient of the two, as it avoids the repeated invocations of count.) See my answer here for a description of the method and links to its use.
In a nutshell, it differs from Array#- as illustrated in the following example:

a = [1,2,3,4,3,2,4,2]
b = [2,3,4,4,4]

a - b #=> [1]
a.difference b #=> [1, 3, 2, 2]

One day I'd like to see it as a built-in.

For the present problem, if:

arr = [1,2,3,4,3,4]

the duplicate elements are given by:

arr.difference(arr.uniq).uniq
#=> [3, 4]

Duplicate array elements in Ruby

How about

rangers.zip(rangers).flatten

using Array#zip and Array#flatten?

A solution that might generalize a bit better for your second request might be:

rangers.flat_map { |ranger| [ranger] * 2 }

using Enumerable#flat_map.
Here you can just replace the 2 with any value or variable.

Ruby - Iterate through each string inside an array and remove repeated characters

Input

array = ["abc", "abc", "xxzzyyww", "aaaaa"]

Code

p array.map { _1.chars.uniq.join }

Output

["abc", "abc", "xzyw", "a"]

How do I detect duplicate values within an array in Ruby?

You can create a hash to store number of times any element is repeated. Thus iterating over array just once.

h = Hash.new(0)
['a','b','b','c'].each{ |e| h[e] += 1 }

Should result

 {"a"=>1, "b"=>2, "c"=>1}


Related Topics



Leave a reply



Submit