Cut each N symbol from array

Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
2
down vote
favorite
What is the most efficient and productive way to cut each N symbol from a string?
For instance,
n = 5;
str = '1234A1234B1234C';
result: "123412341234"
This is my approach:
def delete_each_n(str, n)
i = n
str.length/n.times do
str.slice!(i-1)
i += (n - 1)
end
str
end
ruby
add a comment |Â
up vote
2
down vote
favorite
What is the most efficient and productive way to cut each N symbol from a string?
For instance,
n = 5;
str = '1234A1234B1234C';
result: "123412341234"
This is my approach:
def delete_each_n(str, n)
i = n
str.length/n.times do
str.slice!(i-1)
i += (n - 1)
end
str
end
ruby
Would you mind adding some test cases? I just tried with your method, and gotdelete_each_n("abcabc", 2) #=> "acbc", when I expected that you wanted "acb".
â thesecretmaster
Feb 11 at 20:21
1
@thesecretmaster: It's a bug. See my answer.
â Eric Duminil
Feb 11 at 22:31
Thanks @EricDuminil. You've written a much better answer than I have (so +1), but I'm still going to leave mine there as a different way to do it.
â thesecretmaster
Feb 11 at 23:14
add a comment |Â
up vote
2
down vote
favorite
up vote
2
down vote
favorite
What is the most efficient and productive way to cut each N symbol from a string?
For instance,
n = 5;
str = '1234A1234B1234C';
result: "123412341234"
This is my approach:
def delete_each_n(str, n)
i = n
str.length/n.times do
str.slice!(i-1)
i += (n - 1)
end
str
end
ruby
What is the most efficient and productive way to cut each N symbol from a string?
For instance,
n = 5;
str = '1234A1234B1234C';
result: "123412341234"
This is my approach:
def delete_each_n(str, n)
i = n
str.length/n.times do
str.slice!(i-1)
i += (n - 1)
end
str
end
ruby
edited Feb 11 at 16:17
asked Feb 11 at 16:11
TiSer
1135
1135
Would you mind adding some test cases? I just tried with your method, and gotdelete_each_n("abcabc", 2) #=> "acbc", when I expected that you wanted "acb".
â thesecretmaster
Feb 11 at 20:21
1
@thesecretmaster: It's a bug. See my answer.
â Eric Duminil
Feb 11 at 22:31
Thanks @EricDuminil. You've written a much better answer than I have (so +1), but I'm still going to leave mine there as a different way to do it.
â thesecretmaster
Feb 11 at 23:14
add a comment |Â
Would you mind adding some test cases? I just tried with your method, and gotdelete_each_n("abcabc", 2) #=> "acbc", when I expected that you wanted "acb".
â thesecretmaster
Feb 11 at 20:21
1
@thesecretmaster: It's a bug. See my answer.
â Eric Duminil
Feb 11 at 22:31
Thanks @EricDuminil. You've written a much better answer than I have (so +1), but I'm still going to leave mine there as a different way to do it.
â thesecretmaster
Feb 11 at 23:14
Would you mind adding some test cases? I just tried with your method, and got
delete_each_n("abcabc", 2) #=> "acbc", when I expected that you wanted "acb".â thesecretmaster
Feb 11 at 20:21
Would you mind adding some test cases? I just tried with your method, and got
delete_each_n("abcabc", 2) #=> "acbc", when I expected that you wanted "acb".â thesecretmaster
Feb 11 at 20:21
1
1
@thesecretmaster: It's a bug. See my answer.
â Eric Duminil
Feb 11 at 22:31
@thesecretmaster: It's a bug. See my answer.
â Eric Duminil
Feb 11 at 22:31
Thanks @EricDuminil. You've written a much better answer than I have (so +1), but I'm still going to leave mine there as a different way to do it.
â thesecretmaster
Feb 11 at 23:14
Thanks @EricDuminil. You've written a much better answer than I have (so +1), but I'm still going to leave mine there as a different way to do it.
â thesecretmaster
Feb 11 at 23:14
add a comment |Â
4 Answers
4
active
oldest
votes
up vote
1
down vote
accepted
If you're interested in performance, and your particular circumstances restrict the characters in the string to those in the ASCII range, then there is something to be said for avoiding the overhead of multibyte character operations and assuming single byte operations will work for you.
This is 2.4.2 on a MacBook Pro, and you'll see that method 4, using bytesize and byteslice, and avoiding regexp and map, is twice as fast as the next fastest on longer strings, and five times as fast on the original example.
2.4.2 :001 > def method1(string, n)
2.4.2 :002?> string.gsub(/.#n/)
2.4.2 :003?> end
=> :method1
2.4.2 :004 >
2.4.2 :005 > def method2(string, index)
2.4.2 :006?> # Here I use a regular expression to split the string every n characters
2.4.2 :007 > substrings = string.split(%r(.#index))
2.4.2 :008?> .reject(&:empty?) # And cut out any empty strings that appear
2.4.2 :009?>
2.4.2 :010 > # Then we can merge the substrings together, without the list character in each substring
2.4.2 :011 > substrings.map do |substring|
2.4.2 :012 > substring.length < index ? substring : substring[0..-2]
2.4.2 :013?> end.join
2.4.2 :014?> end
=> :method2
2.4.2 :015 >
2.4.2 :016 > def method3(string, index)
2.4.2 :017?> string.gsub(/(.#index-1)./, '\1')
2.4.2 :018?> end
=> :method3
2.4.2 :019 >
2.4.2 :020 > def method4(string, n)
2.4.2 :021?> length = n - 1
2.4.2 :022?> (0..(string.bytesize / n)).each_with_object("") do |x, new_string|
2.4.2 :023 > new_string << string.byteslice(x*n, length)
2.4.2 :024?> end
2.4.2 :025?> end
=> :method4
2.4.2 :026 >
2.4.2 :027 > require 'benchmark'
=> true
2.4.2 :028 >
2.4.2 :029 > runs = 100000
=> 100000
2.4.2 :030 > Benchmark.bm(7) do |x|
2.4.2 :031 > string = '1234A1234B1234C'
2.4.2 :032?> n = 5
2.4.2 :033?> x.report("method 0") runs.times
2.4.2 :034?> x.report("method 1") runs.times method1(string, n)
2.4.2 :035?> x.report("method 2") runs.times method2(string, n)
2.4.2 :036?> x.report("method 3") runs.times method3(string, n)
2.4.2 :037?> x.report("method 4") runs.times method4(string, n)
2.4.2 :038?> end ; ""
user system total real
method 0 0.000000 0.000000 0.000000 ( 0.003366)
method 1 0.570000 0.000000 0.570000 ( 0.572950)
method 2 0.670000 0.000000 0.670000 ( 0.666871)
method 3 0.750000 0.000000 0.750000 ( 0.763856)
method 4 0.120000 0.000000 0.120000 ( 0.118647)
=> ""
2.4.2 :039 >
2.4.2 :040 > runs = 50000
=> 50000
2.4.2 :041 > Benchmark.bm(7) do |x|
2.4.2 :042 > string = '1234A1234B1234C'*50
2.4.2 :043?> n = 2
2.4.2 :044?> x.report("method 0") runs.times
2.4.2 :045?> x.report("method 1") runs.times method1(string, n)
2.4.2 :046?> x.report("method 2") runs.times method2(string, n)
2.4.2 :047?> x.report("method 3") runs.times method3(string, n)
2.4.2 :048?> x.report("method 4") runs.times method4(string, n)
2.4.2 :049?> end ; ""
user system total real
method 0 0.000000 0.000000 0.000000 ( 0.001685)
method 1 7.110000 0.010000 7.120000 ( 7.131064)
method 2 11.450000 0.010000 11.460000 ( 11.475658)
method 3 9.640000 0.070000 9.710000 ( 9.721599)
method 4 3.750000 0.010000 3.760000 ( 3.758784)
=> ""
2.4.2 :050 >
add a comment |Â
up vote
3
down vote
Your code
You have a sneaky bug in your code!
1000/2.times
You seem to think that this code would display 500 numbers between 0 and 499.
It doesn't. Instead, it displays 0, 1, and returns 500.
You need to replace str.length/n.times do with (str.length/n).times do.
Alternative
You can use gsub to look for the substrings, chop them and replace them:
def delete_every_nth_char(string, n)
string.gsub(/.#n/)
end
delete_every_nth_char('1234A1234B1234C', 5)
# "123412341234"
delete_every_nth_char('ABAB', 2)
# "AA"
delete_every_nth_char('ABA', 2)
# "AA"
delete_every_nth_char('ABA', 1)
# ""
delete_every_nth_char('ABA', 5)
# "ABA"
It is concise and probably faster than splitting and joining the strings manually.
add a comment |Â
up vote
2
down vote
One way to do it would be to split the string into substrings that are the length n, then remove the last element from each substring. So, for example:
def delete_each_n(string, index)
# Here I use a regular expression to split the string every n characters
substrings = string.split(%r(.#index))
.reject(&:empty?) # And cut out any empty strings that appear
# Then we can merge the substrings together, without the list character in each substring
substrings.map do |substring|
substring.length < index ? substring : substring[0..-2]
end.join
end
add a comment |Â
up vote
0
down vote
Another way would be:
str.gsub(/(.#n-1)./, '\1')
1
I think you should explain why your alternative is better.
â Billal BEGUERADJ
Feb 12 at 7:15
add a comment |Â
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
If you're interested in performance, and your particular circumstances restrict the characters in the string to those in the ASCII range, then there is something to be said for avoiding the overhead of multibyte character operations and assuming single byte operations will work for you.
This is 2.4.2 on a MacBook Pro, and you'll see that method 4, using bytesize and byteslice, and avoiding regexp and map, is twice as fast as the next fastest on longer strings, and five times as fast on the original example.
2.4.2 :001 > def method1(string, n)
2.4.2 :002?> string.gsub(/.#n/)
2.4.2 :003?> end
=> :method1
2.4.2 :004 >
2.4.2 :005 > def method2(string, index)
2.4.2 :006?> # Here I use a regular expression to split the string every n characters
2.4.2 :007 > substrings = string.split(%r(.#index))
2.4.2 :008?> .reject(&:empty?) # And cut out any empty strings that appear
2.4.2 :009?>
2.4.2 :010 > # Then we can merge the substrings together, without the list character in each substring
2.4.2 :011 > substrings.map do |substring|
2.4.2 :012 > substring.length < index ? substring : substring[0..-2]
2.4.2 :013?> end.join
2.4.2 :014?> end
=> :method2
2.4.2 :015 >
2.4.2 :016 > def method3(string, index)
2.4.2 :017?> string.gsub(/(.#index-1)./, '\1')
2.4.2 :018?> end
=> :method3
2.4.2 :019 >
2.4.2 :020 > def method4(string, n)
2.4.2 :021?> length = n - 1
2.4.2 :022?> (0..(string.bytesize / n)).each_with_object("") do |x, new_string|
2.4.2 :023 > new_string << string.byteslice(x*n, length)
2.4.2 :024?> end
2.4.2 :025?> end
=> :method4
2.4.2 :026 >
2.4.2 :027 > require 'benchmark'
=> true
2.4.2 :028 >
2.4.2 :029 > runs = 100000
=> 100000
2.4.2 :030 > Benchmark.bm(7) do |x|
2.4.2 :031 > string = '1234A1234B1234C'
2.4.2 :032?> n = 5
2.4.2 :033?> x.report("method 0") runs.times
2.4.2 :034?> x.report("method 1") runs.times method1(string, n)
2.4.2 :035?> x.report("method 2") runs.times method2(string, n)
2.4.2 :036?> x.report("method 3") runs.times method3(string, n)
2.4.2 :037?> x.report("method 4") runs.times method4(string, n)
2.4.2 :038?> end ; ""
user system total real
method 0 0.000000 0.000000 0.000000 ( 0.003366)
method 1 0.570000 0.000000 0.570000 ( 0.572950)
method 2 0.670000 0.000000 0.670000 ( 0.666871)
method 3 0.750000 0.000000 0.750000 ( 0.763856)
method 4 0.120000 0.000000 0.120000 ( 0.118647)
=> ""
2.4.2 :039 >
2.4.2 :040 > runs = 50000
=> 50000
2.4.2 :041 > Benchmark.bm(7) do |x|
2.4.2 :042 > string = '1234A1234B1234C'*50
2.4.2 :043?> n = 2
2.4.2 :044?> x.report("method 0") runs.times
2.4.2 :045?> x.report("method 1") runs.times method1(string, n)
2.4.2 :046?> x.report("method 2") runs.times method2(string, n)
2.4.2 :047?> x.report("method 3") runs.times method3(string, n)
2.4.2 :048?> x.report("method 4") runs.times method4(string, n)
2.4.2 :049?> end ; ""
user system total real
method 0 0.000000 0.000000 0.000000 ( 0.001685)
method 1 7.110000 0.010000 7.120000 ( 7.131064)
method 2 11.450000 0.010000 11.460000 ( 11.475658)
method 3 9.640000 0.070000 9.710000 ( 9.721599)
method 4 3.750000 0.010000 3.760000 ( 3.758784)
=> ""
2.4.2 :050 >
add a comment |Â
up vote
1
down vote
accepted
If you're interested in performance, and your particular circumstances restrict the characters in the string to those in the ASCII range, then there is something to be said for avoiding the overhead of multibyte character operations and assuming single byte operations will work for you.
This is 2.4.2 on a MacBook Pro, and you'll see that method 4, using bytesize and byteslice, and avoiding regexp and map, is twice as fast as the next fastest on longer strings, and five times as fast on the original example.
2.4.2 :001 > def method1(string, n)
2.4.2 :002?> string.gsub(/.#n/)
2.4.2 :003?> end
=> :method1
2.4.2 :004 >
2.4.2 :005 > def method2(string, index)
2.4.2 :006?> # Here I use a regular expression to split the string every n characters
2.4.2 :007 > substrings = string.split(%r(.#index))
2.4.2 :008?> .reject(&:empty?) # And cut out any empty strings that appear
2.4.2 :009?>
2.4.2 :010 > # Then we can merge the substrings together, without the list character in each substring
2.4.2 :011 > substrings.map do |substring|
2.4.2 :012 > substring.length < index ? substring : substring[0..-2]
2.4.2 :013?> end.join
2.4.2 :014?> end
=> :method2
2.4.2 :015 >
2.4.2 :016 > def method3(string, index)
2.4.2 :017?> string.gsub(/(.#index-1)./, '\1')
2.4.2 :018?> end
=> :method3
2.4.2 :019 >
2.4.2 :020 > def method4(string, n)
2.4.2 :021?> length = n - 1
2.4.2 :022?> (0..(string.bytesize / n)).each_with_object("") do |x, new_string|
2.4.2 :023 > new_string << string.byteslice(x*n, length)
2.4.2 :024?> end
2.4.2 :025?> end
=> :method4
2.4.2 :026 >
2.4.2 :027 > require 'benchmark'
=> true
2.4.2 :028 >
2.4.2 :029 > runs = 100000
=> 100000
2.4.2 :030 > Benchmark.bm(7) do |x|
2.4.2 :031 > string = '1234A1234B1234C'
2.4.2 :032?> n = 5
2.4.2 :033?> x.report("method 0") runs.times
2.4.2 :034?> x.report("method 1") runs.times method1(string, n)
2.4.2 :035?> x.report("method 2") runs.times method2(string, n)
2.4.2 :036?> x.report("method 3") runs.times method3(string, n)
2.4.2 :037?> x.report("method 4") runs.times method4(string, n)
2.4.2 :038?> end ; ""
user system total real
method 0 0.000000 0.000000 0.000000 ( 0.003366)
method 1 0.570000 0.000000 0.570000 ( 0.572950)
method 2 0.670000 0.000000 0.670000 ( 0.666871)
method 3 0.750000 0.000000 0.750000 ( 0.763856)
method 4 0.120000 0.000000 0.120000 ( 0.118647)
=> ""
2.4.2 :039 >
2.4.2 :040 > runs = 50000
=> 50000
2.4.2 :041 > Benchmark.bm(7) do |x|
2.4.2 :042 > string = '1234A1234B1234C'*50
2.4.2 :043?> n = 2
2.4.2 :044?> x.report("method 0") runs.times
2.4.2 :045?> x.report("method 1") runs.times method1(string, n)
2.4.2 :046?> x.report("method 2") runs.times method2(string, n)
2.4.2 :047?> x.report("method 3") runs.times method3(string, n)
2.4.2 :048?> x.report("method 4") runs.times method4(string, n)
2.4.2 :049?> end ; ""
user system total real
method 0 0.000000 0.000000 0.000000 ( 0.001685)
method 1 7.110000 0.010000 7.120000 ( 7.131064)
method 2 11.450000 0.010000 11.460000 ( 11.475658)
method 3 9.640000 0.070000 9.710000 ( 9.721599)
method 4 3.750000 0.010000 3.760000 ( 3.758784)
=> ""
2.4.2 :050 >
add a comment |Â
up vote
1
down vote
accepted
up vote
1
down vote
accepted
If you're interested in performance, and your particular circumstances restrict the characters in the string to those in the ASCII range, then there is something to be said for avoiding the overhead of multibyte character operations and assuming single byte operations will work for you.
This is 2.4.2 on a MacBook Pro, and you'll see that method 4, using bytesize and byteslice, and avoiding regexp and map, is twice as fast as the next fastest on longer strings, and five times as fast on the original example.
2.4.2 :001 > def method1(string, n)
2.4.2 :002?> string.gsub(/.#n/)
2.4.2 :003?> end
=> :method1
2.4.2 :004 >
2.4.2 :005 > def method2(string, index)
2.4.2 :006?> # Here I use a regular expression to split the string every n characters
2.4.2 :007 > substrings = string.split(%r(.#index))
2.4.2 :008?> .reject(&:empty?) # And cut out any empty strings that appear
2.4.2 :009?>
2.4.2 :010 > # Then we can merge the substrings together, without the list character in each substring
2.4.2 :011 > substrings.map do |substring|
2.4.2 :012 > substring.length < index ? substring : substring[0..-2]
2.4.2 :013?> end.join
2.4.2 :014?> end
=> :method2
2.4.2 :015 >
2.4.2 :016 > def method3(string, index)
2.4.2 :017?> string.gsub(/(.#index-1)./, '\1')
2.4.2 :018?> end
=> :method3
2.4.2 :019 >
2.4.2 :020 > def method4(string, n)
2.4.2 :021?> length = n - 1
2.4.2 :022?> (0..(string.bytesize / n)).each_with_object("") do |x, new_string|
2.4.2 :023 > new_string << string.byteslice(x*n, length)
2.4.2 :024?> end
2.4.2 :025?> end
=> :method4
2.4.2 :026 >
2.4.2 :027 > require 'benchmark'
=> true
2.4.2 :028 >
2.4.2 :029 > runs = 100000
=> 100000
2.4.2 :030 > Benchmark.bm(7) do |x|
2.4.2 :031 > string = '1234A1234B1234C'
2.4.2 :032?> n = 5
2.4.2 :033?> x.report("method 0") runs.times
2.4.2 :034?> x.report("method 1") runs.times method1(string, n)
2.4.2 :035?> x.report("method 2") runs.times method2(string, n)
2.4.2 :036?> x.report("method 3") runs.times method3(string, n)
2.4.2 :037?> x.report("method 4") runs.times method4(string, n)
2.4.2 :038?> end ; ""
user system total real
method 0 0.000000 0.000000 0.000000 ( 0.003366)
method 1 0.570000 0.000000 0.570000 ( 0.572950)
method 2 0.670000 0.000000 0.670000 ( 0.666871)
method 3 0.750000 0.000000 0.750000 ( 0.763856)
method 4 0.120000 0.000000 0.120000 ( 0.118647)
=> ""
2.4.2 :039 >
2.4.2 :040 > runs = 50000
=> 50000
2.4.2 :041 > Benchmark.bm(7) do |x|
2.4.2 :042 > string = '1234A1234B1234C'*50
2.4.2 :043?> n = 2
2.4.2 :044?> x.report("method 0") runs.times
2.4.2 :045?> x.report("method 1") runs.times method1(string, n)
2.4.2 :046?> x.report("method 2") runs.times method2(string, n)
2.4.2 :047?> x.report("method 3") runs.times method3(string, n)
2.4.2 :048?> x.report("method 4") runs.times method4(string, n)
2.4.2 :049?> end ; ""
user system total real
method 0 0.000000 0.000000 0.000000 ( 0.001685)
method 1 7.110000 0.010000 7.120000 ( 7.131064)
method 2 11.450000 0.010000 11.460000 ( 11.475658)
method 3 9.640000 0.070000 9.710000 ( 9.721599)
method 4 3.750000 0.010000 3.760000 ( 3.758784)
=> ""
2.4.2 :050 >
If you're interested in performance, and your particular circumstances restrict the characters in the string to those in the ASCII range, then there is something to be said for avoiding the overhead of multibyte character operations and assuming single byte operations will work for you.
This is 2.4.2 on a MacBook Pro, and you'll see that method 4, using bytesize and byteslice, and avoiding regexp and map, is twice as fast as the next fastest on longer strings, and five times as fast on the original example.
2.4.2 :001 > def method1(string, n)
2.4.2 :002?> string.gsub(/.#n/)
2.4.2 :003?> end
=> :method1
2.4.2 :004 >
2.4.2 :005 > def method2(string, index)
2.4.2 :006?> # Here I use a regular expression to split the string every n characters
2.4.2 :007 > substrings = string.split(%r(.#index))
2.4.2 :008?> .reject(&:empty?) # And cut out any empty strings that appear
2.4.2 :009?>
2.4.2 :010 > # Then we can merge the substrings together, without the list character in each substring
2.4.2 :011 > substrings.map do |substring|
2.4.2 :012 > substring.length < index ? substring : substring[0..-2]
2.4.2 :013?> end.join
2.4.2 :014?> end
=> :method2
2.4.2 :015 >
2.4.2 :016 > def method3(string, index)
2.4.2 :017?> string.gsub(/(.#index-1)./, '\1')
2.4.2 :018?> end
=> :method3
2.4.2 :019 >
2.4.2 :020 > def method4(string, n)
2.4.2 :021?> length = n - 1
2.4.2 :022?> (0..(string.bytesize / n)).each_with_object("") do |x, new_string|
2.4.2 :023 > new_string << string.byteslice(x*n, length)
2.4.2 :024?> end
2.4.2 :025?> end
=> :method4
2.4.2 :026 >
2.4.2 :027 > require 'benchmark'
=> true
2.4.2 :028 >
2.4.2 :029 > runs = 100000
=> 100000
2.4.2 :030 > Benchmark.bm(7) do |x|
2.4.2 :031 > string = '1234A1234B1234C'
2.4.2 :032?> n = 5
2.4.2 :033?> x.report("method 0") runs.times
2.4.2 :034?> x.report("method 1") runs.times method1(string, n)
2.4.2 :035?> x.report("method 2") runs.times method2(string, n)
2.4.2 :036?> x.report("method 3") runs.times method3(string, n)
2.4.2 :037?> x.report("method 4") runs.times method4(string, n)
2.4.2 :038?> end ; ""
user system total real
method 0 0.000000 0.000000 0.000000 ( 0.003366)
method 1 0.570000 0.000000 0.570000 ( 0.572950)
method 2 0.670000 0.000000 0.670000 ( 0.666871)
method 3 0.750000 0.000000 0.750000 ( 0.763856)
method 4 0.120000 0.000000 0.120000 ( 0.118647)
=> ""
2.4.2 :039 >
2.4.2 :040 > runs = 50000
=> 50000
2.4.2 :041 > Benchmark.bm(7) do |x|
2.4.2 :042 > string = '1234A1234B1234C'*50
2.4.2 :043?> n = 2
2.4.2 :044?> x.report("method 0") runs.times
2.4.2 :045?> x.report("method 1") runs.times method1(string, n)
2.4.2 :046?> x.report("method 2") runs.times method2(string, n)
2.4.2 :047?> x.report("method 3") runs.times method3(string, n)
2.4.2 :048?> x.report("method 4") runs.times method4(string, n)
2.4.2 :049?> end ; ""
user system total real
method 0 0.000000 0.000000 0.000000 ( 0.001685)
method 1 7.110000 0.010000 7.120000 ( 7.131064)
method 2 11.450000 0.010000 11.460000 ( 11.475658)
method 3 9.640000 0.070000 9.710000 ( 9.721599)
method 4 3.750000 0.010000 3.760000 ( 3.758784)
=> ""
2.4.2 :050 >
answered Feb 13 at 20:16
David Aldridge
36518
36518
add a comment |Â
add a comment |Â
up vote
3
down vote
Your code
You have a sneaky bug in your code!
1000/2.times
You seem to think that this code would display 500 numbers between 0 and 499.
It doesn't. Instead, it displays 0, 1, and returns 500.
You need to replace str.length/n.times do with (str.length/n).times do.
Alternative
You can use gsub to look for the substrings, chop them and replace them:
def delete_every_nth_char(string, n)
string.gsub(/.#n/)
end
delete_every_nth_char('1234A1234B1234C', 5)
# "123412341234"
delete_every_nth_char('ABAB', 2)
# "AA"
delete_every_nth_char('ABA', 2)
# "AA"
delete_every_nth_char('ABA', 1)
# ""
delete_every_nth_char('ABA', 5)
# "ABA"
It is concise and probably faster than splitting and joining the strings manually.
add a comment |Â
up vote
3
down vote
Your code
You have a sneaky bug in your code!
1000/2.times
You seem to think that this code would display 500 numbers between 0 and 499.
It doesn't. Instead, it displays 0, 1, and returns 500.
You need to replace str.length/n.times do with (str.length/n).times do.
Alternative
You can use gsub to look for the substrings, chop them and replace them:
def delete_every_nth_char(string, n)
string.gsub(/.#n/)
end
delete_every_nth_char('1234A1234B1234C', 5)
# "123412341234"
delete_every_nth_char('ABAB', 2)
# "AA"
delete_every_nth_char('ABA', 2)
# "AA"
delete_every_nth_char('ABA', 1)
# ""
delete_every_nth_char('ABA', 5)
# "ABA"
It is concise and probably faster than splitting and joining the strings manually.
add a comment |Â
up vote
3
down vote
up vote
3
down vote
Your code
You have a sneaky bug in your code!
1000/2.times
You seem to think that this code would display 500 numbers between 0 and 499.
It doesn't. Instead, it displays 0, 1, and returns 500.
You need to replace str.length/n.times do with (str.length/n).times do.
Alternative
You can use gsub to look for the substrings, chop them and replace them:
def delete_every_nth_char(string, n)
string.gsub(/.#n/)
end
delete_every_nth_char('1234A1234B1234C', 5)
# "123412341234"
delete_every_nth_char('ABAB', 2)
# "AA"
delete_every_nth_char('ABA', 2)
# "AA"
delete_every_nth_char('ABA', 1)
# ""
delete_every_nth_char('ABA', 5)
# "ABA"
It is concise and probably faster than splitting and joining the strings manually.
Your code
You have a sneaky bug in your code!
1000/2.times
You seem to think that this code would display 500 numbers between 0 and 499.
It doesn't. Instead, it displays 0, 1, and returns 500.
You need to replace str.length/n.times do with (str.length/n).times do.
Alternative
You can use gsub to look for the substrings, chop them and replace them:
def delete_every_nth_char(string, n)
string.gsub(/.#n/)
end
delete_every_nth_char('1234A1234B1234C', 5)
# "123412341234"
delete_every_nth_char('ABAB', 2)
# "AA"
delete_every_nth_char('ABA', 2)
# "AA"
delete_every_nth_char('ABA', 1)
# ""
delete_every_nth_char('ABA', 5)
# "ABA"
It is concise and probably faster than splitting and joining the strings manually.
edited Feb 11 at 22:30
answered Feb 11 at 22:15
Eric Duminil
1,8501613
1,8501613
add a comment |Â
add a comment |Â
up vote
2
down vote
One way to do it would be to split the string into substrings that are the length n, then remove the last element from each substring. So, for example:
def delete_each_n(string, index)
# Here I use a regular expression to split the string every n characters
substrings = string.split(%r(.#index))
.reject(&:empty?) # And cut out any empty strings that appear
# Then we can merge the substrings together, without the list character in each substring
substrings.map do |substring|
substring.length < index ? substring : substring[0..-2]
end.join
end
add a comment |Â
up vote
2
down vote
One way to do it would be to split the string into substrings that are the length n, then remove the last element from each substring. So, for example:
def delete_each_n(string, index)
# Here I use a regular expression to split the string every n characters
substrings = string.split(%r(.#index))
.reject(&:empty?) # And cut out any empty strings that appear
# Then we can merge the substrings together, without the list character in each substring
substrings.map do |substring|
substring.length < index ? substring : substring[0..-2]
end.join
end
add a comment |Â
up vote
2
down vote
up vote
2
down vote
One way to do it would be to split the string into substrings that are the length n, then remove the last element from each substring. So, for example:
def delete_each_n(string, index)
# Here I use a regular expression to split the string every n characters
substrings = string.split(%r(.#index))
.reject(&:empty?) # And cut out any empty strings that appear
# Then we can merge the substrings together, without the list character in each substring
substrings.map do |substring|
substring.length < index ? substring : substring[0..-2]
end.join
end
One way to do it would be to split the string into substrings that are the length n, then remove the last element from each substring. So, for example:
def delete_each_n(string, index)
# Here I use a regular expression to split the string every n characters
substrings = string.split(%r(.#index))
.reject(&:empty?) # And cut out any empty strings that appear
# Then we can merge the substrings together, without the list character in each substring
substrings.map do |substring|
substring.length < index ? substring : substring[0..-2]
end.join
end
answered Feb 11 at 20:45
thesecretmaster
33319
33319
add a comment |Â
add a comment |Â
up vote
0
down vote
Another way would be:
str.gsub(/(.#n-1)./, '\1')
1
I think you should explain why your alternative is better.
â Billal BEGUERADJ
Feb 12 at 7:15
add a comment |Â
up vote
0
down vote
Another way would be:
str.gsub(/(.#n-1)./, '\1')
1
I think you should explain why your alternative is better.
â Billal BEGUERADJ
Feb 12 at 7:15
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Another way would be:
str.gsub(/(.#n-1)./, '\1')
Another way would be:
str.gsub(/(.#n-1)./, '\1')
answered Feb 12 at 4:49
Marc Rohloff
2,57735
2,57735
1
I think you should explain why your alternative is better.
â Billal BEGUERADJ
Feb 12 at 7:15
add a comment |Â
1
I think you should explain why your alternative is better.
â Billal BEGUERADJ
Feb 12 at 7:15
1
1
I think you should explain why your alternative is better.
â Billal BEGUERADJ
Feb 12 at 7:15
I think you should explain why your alternative is better.
â Billal BEGUERADJ
Feb 12 at 7:15
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f187319%2fcut-each-n-symbol-from-array%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Would you mind adding some test cases? I just tried with your method, and got
delete_each_n("abcabc", 2) #=> "acbc", when I expected that you wanted "acb".â thesecretmaster
Feb 11 at 20:21
1
@thesecretmaster: It's a bug. See my answer.
â Eric Duminil
Feb 11 at 22:31
Thanks @EricDuminil. You've written a much better answer than I have (so +1), but I'm still going to leave mine there as a different way to do it.
â thesecretmaster
Feb 11 at 23:14