Вопрос

If I have a string like 'Lorem Ipsum', I need a method, which returns a random part of the string, like 'rem I', 'Lor', etc. (UPDATE: the method should not return empty strings). So far I have come up with this:

def random_slice string
  start = rand string.size - 2
  finish = rand start + 1..string.size - 1
  word[start..finish]
end

Are there any better alternatives?

Это было полезно?

Решение

You can write it simpler with:

s[rand(s.length), rand(s.length - 1) + 1]

Другие советы

Have a look at the String#slice method.

s = 'Lorem Ipsum'
s.slice(rand(s.size), rand(s.size) + 1)
=> "orem Ip"

If passed a start index and a length, returns a substring containing length characters starting at the index.

Just made a simple benchmark of the randomness of the accepted answer:

s = "0123456789"
count = Hash.new(0)
SAMPLE_SIZE = 5000000

SAMPLE_SIZE.times do
  sub = s[rand(s.length), rand(s.length - 1) + 1]
  count[sub] += 1
end

count.sort_by{|k,v| -v}.each do |k, v|
  puts "#{k.ljust(10)} #{v.to_f*100/SAMPLE_SIZE}%"
end

The results are:

9          9.9888%
89         8.87602%
789        7.79196%
6789       6.66138%
56789      5.5665%
456789     4.45512%
3456789    3.32218%
23456789   2.2117%
23456      1.12276%
123456789  1.1204%
...        # all about 1% for the others

It's generally not a random solution. We can prove that the actual result follows this trend (assume that rand generates real random values).

A more random one would be:

  1. generate all possible substrings into an array, as pointed out in this question.
  2. call Array#sample. You can cache the result from the first step and do step 2 multiple times.

Maybe the accepted answer just met the requirements, and it's really simple.

str = "Lorem ipsum your text goes here"
boundaries = [rand(str.size), rand(str.size)].sort
p str[Range.new(*boundaries)] # => "rem ipsum your"
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top