Cut each N symbol from array

The name of the pictureThe name of the pictureThe name of the pictureClash 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






share|improve this question





















  • 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
















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






share|improve this question





















  • 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












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






share|improve this question













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








share|improve this question












share|improve this question




share|improve this question








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 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
















  • 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















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










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 >





share|improve this answer




























    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.






    share|improve this answer






























      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





      share|improve this answer




























        up vote
        0
        down vote













        Another way would be:



         str.gsub(/(.#n-1)./, '\1')





        share|improve this answer

















        • 1




          I think you should explain why your alternative is better.
          – Billal BEGUERADJ
          Feb 12 at 7:15










        Your Answer




        StackExchange.ifUsing("editor", function ()
        return StackExchange.using("mathjaxEditing", function ()
        StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
        StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
        );
        );
        , "mathjax-editing");

        StackExchange.ifUsing("editor", function ()
        StackExchange.using("externalEditor", function ()
        StackExchange.using("snippets", function ()
        StackExchange.snippets.init();
        );
        );
        , "code-snippets");

        StackExchange.ready(function()
        var channelOptions =
        tags: "".split(" "),
        id: "196"
        ;
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function()
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled)
        StackExchange.using("snippets", function()
        createEditor();
        );

        else
        createEditor();

        );

        function createEditor()
        StackExchange.prepareEditor(
        heartbeatType: 'answer',
        convertImagesToLinks: false,
        noModals: false,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: null,
        bindNavPrevention: true,
        postfix: "",
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        );



        );








         

        draft saved


        draft discarded


















        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






























        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 >





        share|improve this answer

























          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 >





          share|improve this answer























            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 >





            share|improve this answer













            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 >






            share|improve this answer













            share|improve this answer



            share|improve this answer











            answered Feb 13 at 20:16









            David Aldridge

            36518




            36518






















                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.






                share|improve this answer



























                  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.






                  share|improve this answer

























                    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.






                    share|improve this answer















                    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.







                    share|improve this answer















                    share|improve this answer



                    share|improve this answer








                    edited Feb 11 at 22:30


























                    answered Feb 11 at 22:15









                    Eric Duminil

                    1,8501613




                    1,8501613




















                        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





                        share|improve this answer

























                          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





                          share|improve this answer























                            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





                            share|improve this answer













                            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






                            share|improve this answer













                            share|improve this answer



                            share|improve this answer











                            answered Feb 11 at 20:45









                            thesecretmaster

                            33319




                            33319




















                                up vote
                                0
                                down vote













                                Another way would be:



                                 str.gsub(/(.#n-1)./, '\1')





                                share|improve this answer

















                                • 1




                                  I think you should explain why your alternative is better.
                                  – Billal BEGUERADJ
                                  Feb 12 at 7:15














                                up vote
                                0
                                down vote













                                Another way would be:



                                 str.gsub(/(.#n-1)./, '\1')





                                share|improve this answer

















                                • 1




                                  I think you should explain why your alternative is better.
                                  – Billal BEGUERADJ
                                  Feb 12 at 7:15












                                up vote
                                0
                                down vote










                                up vote
                                0
                                down vote









                                Another way would be:



                                 str.gsub(/(.#n-1)./, '\1')





                                share|improve this answer













                                Another way would be:



                                 str.gsub(/(.#n-1)./, '\1')






                                share|improve this answer













                                share|improve this answer



                                share|improve this answer











                                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












                                • 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












                                 

                                draft saved


                                draft discarded


























                                 


                                draft saved


                                draft discarded














                                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













































































                                Popular posts from this blog

                                Python Lists

                                Aion

                                JavaScript Array Iteration Methods