Delete as many elements from the beginning of an array that match a value, until array reaches a specified...












3














I'm trying to modify an array by deleting values that match a unique ID, but then stop once the first 5 values of the array are valid (i.e. their IDs do not match the undesired ones). If the array has a count <= 5, then this suffices:



all_items = [{"id" => "id01"},{"id" => "id02"},{"id" => "id03"},{"id" => "id04"}]
exclude_ids = ["id01","id02"]
all_items.delete_if { |item| exclude_ids.include?(item["id"])}


and the desired output is [{"id" => "id03"},{"id" => "id04"}].



But in the case where the total count of the array is >= 5, I want to delete only as many of the first items as necessary until the first 5 elements (all_items[0..4]) are all valid within the set criterion, and then stop iterating. If I were to do this:



all_items = [{"id" => "id01"},{"id" => "id02"},{"id" => "id03"},{"id" => "id04"},{"id" => "id05"},{"id" => "id06"},{"id" => "id07"},{"id" => "id08"},{"id" => "id09"},{"id" => "id10"}]
exclude_ids = ["id01","id02","id07"]
all_items.delete_if { |item| exclude_ids.include?(item["id"])}
return all_items[0..4]


I do get the desired output, [{"id" => "id03"},{"id" => "id04"},{"id" => "id05"},{"id" => "id06"},{"id" => "id08"}]. But I want the delete_if to completely stop once it reaches the point where all_items[0..4] already contains 5 valid elements. In this instance, I would want it to break after {"id" => "id08"}, and not even check the remaining values. (If, however, while the delete_if is running, the total count dips below 5, then it should continue iterating over all remaining elements, as it would fall into the category of the first piece of code I posted above, where the count <= 5.)



I know there is a delete_if.with_index, but I'm not sure if it's appropriate in this context, especially since the index would be shifting as items are deleted.



To summarize my question: is there a way to delete as many first items from an array as is required until array[0..x] is populated by desired values, and then stop checking/deleting any remaining items once that count of x is reached?










share|improve this question


















  • 2




    Sounds like drop_while .
    – steenslag
    Nov 20 at 1:56






  • 1




    drop_while will drop elements from the beginning. What if the first four and the sixth elements are valid and you need remove the fifth one to make a run of five?
    – Jörg W Mittag
    Nov 20 at 5:23










  • This is an interesting question, but it is not answered by the answer to which you awarded the greenie. See my comments on that question.
    – Cary Swoveland
    Nov 21 at 4:49
















3














I'm trying to modify an array by deleting values that match a unique ID, but then stop once the first 5 values of the array are valid (i.e. their IDs do not match the undesired ones). If the array has a count <= 5, then this suffices:



all_items = [{"id" => "id01"},{"id" => "id02"},{"id" => "id03"},{"id" => "id04"}]
exclude_ids = ["id01","id02"]
all_items.delete_if { |item| exclude_ids.include?(item["id"])}


and the desired output is [{"id" => "id03"},{"id" => "id04"}].



But in the case where the total count of the array is >= 5, I want to delete only as many of the first items as necessary until the first 5 elements (all_items[0..4]) are all valid within the set criterion, and then stop iterating. If I were to do this:



all_items = [{"id" => "id01"},{"id" => "id02"},{"id" => "id03"},{"id" => "id04"},{"id" => "id05"},{"id" => "id06"},{"id" => "id07"},{"id" => "id08"},{"id" => "id09"},{"id" => "id10"}]
exclude_ids = ["id01","id02","id07"]
all_items.delete_if { |item| exclude_ids.include?(item["id"])}
return all_items[0..4]


I do get the desired output, [{"id" => "id03"},{"id" => "id04"},{"id" => "id05"},{"id" => "id06"},{"id" => "id08"}]. But I want the delete_if to completely stop once it reaches the point where all_items[0..4] already contains 5 valid elements. In this instance, I would want it to break after {"id" => "id08"}, and not even check the remaining values. (If, however, while the delete_if is running, the total count dips below 5, then it should continue iterating over all remaining elements, as it would fall into the category of the first piece of code I posted above, where the count <= 5.)



I know there is a delete_if.with_index, but I'm not sure if it's appropriate in this context, especially since the index would be shifting as items are deleted.



To summarize my question: is there a way to delete as many first items from an array as is required until array[0..x] is populated by desired values, and then stop checking/deleting any remaining items once that count of x is reached?










share|improve this question


















  • 2




    Sounds like drop_while .
    – steenslag
    Nov 20 at 1:56






  • 1




    drop_while will drop elements from the beginning. What if the first four and the sixth elements are valid and you need remove the fifth one to make a run of five?
    – Jörg W Mittag
    Nov 20 at 5:23










  • This is an interesting question, but it is not answered by the answer to which you awarded the greenie. See my comments on that question.
    – Cary Swoveland
    Nov 21 at 4:49














3












3








3







I'm trying to modify an array by deleting values that match a unique ID, but then stop once the first 5 values of the array are valid (i.e. their IDs do not match the undesired ones). If the array has a count <= 5, then this suffices:



all_items = [{"id" => "id01"},{"id" => "id02"},{"id" => "id03"},{"id" => "id04"}]
exclude_ids = ["id01","id02"]
all_items.delete_if { |item| exclude_ids.include?(item["id"])}


and the desired output is [{"id" => "id03"},{"id" => "id04"}].



But in the case where the total count of the array is >= 5, I want to delete only as many of the first items as necessary until the first 5 elements (all_items[0..4]) are all valid within the set criterion, and then stop iterating. If I were to do this:



all_items = [{"id" => "id01"},{"id" => "id02"},{"id" => "id03"},{"id" => "id04"},{"id" => "id05"},{"id" => "id06"},{"id" => "id07"},{"id" => "id08"},{"id" => "id09"},{"id" => "id10"}]
exclude_ids = ["id01","id02","id07"]
all_items.delete_if { |item| exclude_ids.include?(item["id"])}
return all_items[0..4]


I do get the desired output, [{"id" => "id03"},{"id" => "id04"},{"id" => "id05"},{"id" => "id06"},{"id" => "id08"}]. But I want the delete_if to completely stop once it reaches the point where all_items[0..4] already contains 5 valid elements. In this instance, I would want it to break after {"id" => "id08"}, and not even check the remaining values. (If, however, while the delete_if is running, the total count dips below 5, then it should continue iterating over all remaining elements, as it would fall into the category of the first piece of code I posted above, where the count <= 5.)



I know there is a delete_if.with_index, but I'm not sure if it's appropriate in this context, especially since the index would be shifting as items are deleted.



To summarize my question: is there a way to delete as many first items from an array as is required until array[0..x] is populated by desired values, and then stop checking/deleting any remaining items once that count of x is reached?










share|improve this question













I'm trying to modify an array by deleting values that match a unique ID, but then stop once the first 5 values of the array are valid (i.e. their IDs do not match the undesired ones). If the array has a count <= 5, then this suffices:



all_items = [{"id" => "id01"},{"id" => "id02"},{"id" => "id03"},{"id" => "id04"}]
exclude_ids = ["id01","id02"]
all_items.delete_if { |item| exclude_ids.include?(item["id"])}


and the desired output is [{"id" => "id03"},{"id" => "id04"}].



But in the case where the total count of the array is >= 5, I want to delete only as many of the first items as necessary until the first 5 elements (all_items[0..4]) are all valid within the set criterion, and then stop iterating. If I were to do this:



all_items = [{"id" => "id01"},{"id" => "id02"},{"id" => "id03"},{"id" => "id04"},{"id" => "id05"},{"id" => "id06"},{"id" => "id07"},{"id" => "id08"},{"id" => "id09"},{"id" => "id10"}]
exclude_ids = ["id01","id02","id07"]
all_items.delete_if { |item| exclude_ids.include?(item["id"])}
return all_items[0..4]


I do get the desired output, [{"id" => "id03"},{"id" => "id04"},{"id" => "id05"},{"id" => "id06"},{"id" => "id08"}]. But I want the delete_if to completely stop once it reaches the point where all_items[0..4] already contains 5 valid elements. In this instance, I would want it to break after {"id" => "id08"}, and not even check the remaining values. (If, however, while the delete_if is running, the total count dips below 5, then it should continue iterating over all remaining elements, as it would fall into the category of the first piece of code I posted above, where the count <= 5.)



I know there is a delete_if.with_index, but I'm not sure if it's appropriate in this context, especially since the index would be shifting as items are deleted.



To summarize my question: is there a way to delete as many first items from an array as is required until array[0..x] is populated by desired values, and then stop checking/deleting any remaining items once that count of x is reached?







arrays ruby






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 20 at 1:42









lumos

598




598








  • 2




    Sounds like drop_while .
    – steenslag
    Nov 20 at 1:56






  • 1




    drop_while will drop elements from the beginning. What if the first four and the sixth elements are valid and you need remove the fifth one to make a run of five?
    – Jörg W Mittag
    Nov 20 at 5:23










  • This is an interesting question, but it is not answered by the answer to which you awarded the greenie. See my comments on that question.
    – Cary Swoveland
    Nov 21 at 4:49














  • 2




    Sounds like drop_while .
    – steenslag
    Nov 20 at 1:56






  • 1




    drop_while will drop elements from the beginning. What if the first four and the sixth elements are valid and you need remove the fifth one to make a run of five?
    – Jörg W Mittag
    Nov 20 at 5:23










  • This is an interesting question, but it is not answered by the answer to which you awarded the greenie. See my comments on that question.
    – Cary Swoveland
    Nov 21 at 4:49








2




2




Sounds like drop_while .
– steenslag
Nov 20 at 1:56




Sounds like drop_while .
– steenslag
Nov 20 at 1:56




1




1




drop_while will drop elements from the beginning. What if the first four and the sixth elements are valid and you need remove the fifth one to make a run of five?
– Jörg W Mittag
Nov 20 at 5:23




drop_while will drop elements from the beginning. What if the first four and the sixth elements are valid and you need remove the fifth one to make a run of five?
– Jörg W Mittag
Nov 20 at 5:23












This is an interesting question, but it is not answered by the answer to which you awarded the greenie. See my comments on that question.
– Cary Swoveland
Nov 21 at 4:49




This is an interesting question, but it is not answered by the answer to which you awarded the greenie. See my comments on that question.
– Cary Swoveland
Nov 21 at 4:49












3 Answers
3






active

oldest

votes


















1














termination_threshold = 5
all_items = (1..20).to_a
#=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
exclusions = [1,2,7]

all_items.reject! do |n|
break if termination_threshold.zero?
exclude = exclusions.include? n
termination_threshold -= 1 if exclude
exclude
end
#=> [3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

all_items
#=> [3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]


The following could be used if only an array containing the first termination_threshold valid elements of all_items were desired:



all_items.each_with_object() do |e,arr|
arr << e unless exclusions.include?(e)
break arr if arr.size == termination_threshold
end
#=> [3, 4, 5, 6, 8]





share|improve this answer































    1














    If you delete from the original object you end up with all the items that had not been deleted. So, I gues it is better to move just the desired items to a new object:



    all_items.each_with_object() { |item, ary| ary << item if !exclude_ids.include?(item["id"]) and ary.size < 5 }

    #=> [{"id"=>"id03"}, {"id"=>"id04"}, {"id"=>"id05"}, {"id"=>"id06"}, {"id"=>"id08"}]





    share|improve this answer





























      1














      You can use Enumerator::Lazy to achieve what you want:



      all_items = [{"id" => "id01"},{"id" => "id02"},{"id" => "id03"},{"id" => "id04"},{"id" => "id05"},{"id" => "id06"},{"id" => "id07"},{"id" => "id08"},{"id" => "id09"},{"id" => "id10"}]
      exclude_ids = ["id01","id02","id07"]
      all_items.lazy.reject {|item| exclude_ids.include?(item['id']) }.first(5)





      share|improve this answer





















      • This is incorrect as it does not modify all_items. Instead, it returns an array containing the first 5 elements of all_items that are not contained in exclude_ids. The OP was quite specific that elements of all_items were to be removed until the first 5 valid elements of all_items had been identified. The OP even mentioned the use of delete_if (aka reject!, not reject). I considered using a lazy enumerator, but there is no lazy reject!...
        – Cary Swoveland
        Nov 21 at 4:40










      • ...Suppose all_times has 1,000 elements and the first 3 fail the test and the next five pass. An array of elements at offsets 3-7 of all_items is returned and all_items is unchanged. What use is that? The OP wants to use all_items with certain elements removed.
        – Cary Swoveland
        Nov 21 at 4:46












      • @CarySwoveland based on return statement I deduced that the OP is just deleting elements because he wants to return the first five unrejected items, he doesn't care about the input. Moreover if deleting item was so important I assume deleting all the invalid items would have been priority instead of just rejecting to get the first five valid items.
        – rubish
        Nov 21 at 6:36










      • @CarySwoveland sometimes refactoring doesn't simply mean rearranging the code for optimization or readability but identifying the underlying requirements and change the code to match requirements while optimizing and improving readability.
        – rubish
        Nov 21 at 6:38










      • The last sentence of the OP's question unambiguous and is not the question you answered.
        – Cary Swoveland
        Nov 21 at 6:41











      Your Answer






      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: "1"
      };
      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',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53385065%2fdelete-as-many-elements-from-the-beginning-of-an-array-that-match-a-value-until%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1














      termination_threshold = 5
      all_items = (1..20).to_a
      #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
      exclusions = [1,2,7]

      all_items.reject! do |n|
      break if termination_threshold.zero?
      exclude = exclusions.include? n
      termination_threshold -= 1 if exclude
      exclude
      end
      #=> [3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

      all_items
      #=> [3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]


      The following could be used if only an array containing the first termination_threshold valid elements of all_items were desired:



      all_items.each_with_object() do |e,arr|
      arr << e unless exclusions.include?(e)
      break arr if arr.size == termination_threshold
      end
      #=> [3, 4, 5, 6, 8]





      share|improve this answer




























        1














        termination_threshold = 5
        all_items = (1..20).to_a
        #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
        exclusions = [1,2,7]

        all_items.reject! do |n|
        break if termination_threshold.zero?
        exclude = exclusions.include? n
        termination_threshold -= 1 if exclude
        exclude
        end
        #=> [3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

        all_items
        #=> [3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]


        The following could be used if only an array containing the first termination_threshold valid elements of all_items were desired:



        all_items.each_with_object() do |e,arr|
        arr << e unless exclusions.include?(e)
        break arr if arr.size == termination_threshold
        end
        #=> [3, 4, 5, 6, 8]





        share|improve this answer


























          1












          1








          1






          termination_threshold = 5
          all_items = (1..20).to_a
          #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
          exclusions = [1,2,7]

          all_items.reject! do |n|
          break if termination_threshold.zero?
          exclude = exclusions.include? n
          termination_threshold -= 1 if exclude
          exclude
          end
          #=> [3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

          all_items
          #=> [3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]


          The following could be used if only an array containing the first termination_threshold valid elements of all_items were desired:



          all_items.each_with_object() do |e,arr|
          arr << e unless exclusions.include?(e)
          break arr if arr.size == termination_threshold
          end
          #=> [3, 4, 5, 6, 8]





          share|improve this answer














          termination_threshold = 5
          all_items = (1..20).to_a
          #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
          exclusions = [1,2,7]

          all_items.reject! do |n|
          break if termination_threshold.zero?
          exclude = exclusions.include? n
          termination_threshold -= 1 if exclude
          exclude
          end
          #=> [3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

          all_items
          #=> [3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]


          The following could be used if only an array containing the first termination_threshold valid elements of all_items were desired:



          all_items.each_with_object() do |e,arr|
          arr << e unless exclusions.include?(e)
          break arr if arr.size == termination_threshold
          end
          #=> [3, 4, 5, 6, 8]






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 21 at 22:21

























          answered Nov 20 at 7:40









          Cary Swoveland

          67.5k53965




          67.5k53965

























              1














              If you delete from the original object you end up with all the items that had not been deleted. So, I gues it is better to move just the desired items to a new object:



              all_items.each_with_object() { |item, ary| ary << item if !exclude_ids.include?(item["id"]) and ary.size < 5 }

              #=> [{"id"=>"id03"}, {"id"=>"id04"}, {"id"=>"id05"}, {"id"=>"id06"}, {"id"=>"id08"}]





              share|improve this answer


























                1














                If you delete from the original object you end up with all the items that had not been deleted. So, I gues it is better to move just the desired items to a new object:



                all_items.each_with_object() { |item, ary| ary << item if !exclude_ids.include?(item["id"]) and ary.size < 5 }

                #=> [{"id"=>"id03"}, {"id"=>"id04"}, {"id"=>"id05"}, {"id"=>"id06"}, {"id"=>"id08"}]





                share|improve this answer
























                  1












                  1








                  1






                  If you delete from the original object you end up with all the items that had not been deleted. So, I gues it is better to move just the desired items to a new object:



                  all_items.each_with_object() { |item, ary| ary << item if !exclude_ids.include?(item["id"]) and ary.size < 5 }

                  #=> [{"id"=>"id03"}, {"id"=>"id04"}, {"id"=>"id05"}, {"id"=>"id06"}, {"id"=>"id08"}]





                  share|improve this answer












                  If you delete from the original object you end up with all the items that had not been deleted. So, I gues it is better to move just the desired items to a new object:



                  all_items.each_with_object() { |item, ary| ary << item if !exclude_ids.include?(item["id"]) and ary.size < 5 }

                  #=> [{"id"=>"id03"}, {"id"=>"id04"}, {"id"=>"id05"}, {"id"=>"id06"}, {"id"=>"id08"}]






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 20 at 6:25









                  iGian

                  3,0452622




                  3,0452622























                      1














                      You can use Enumerator::Lazy to achieve what you want:



                      all_items = [{"id" => "id01"},{"id" => "id02"},{"id" => "id03"},{"id" => "id04"},{"id" => "id05"},{"id" => "id06"},{"id" => "id07"},{"id" => "id08"},{"id" => "id09"},{"id" => "id10"}]
                      exclude_ids = ["id01","id02","id07"]
                      all_items.lazy.reject {|item| exclude_ids.include?(item['id']) }.first(5)





                      share|improve this answer





















                      • This is incorrect as it does not modify all_items. Instead, it returns an array containing the first 5 elements of all_items that are not contained in exclude_ids. The OP was quite specific that elements of all_items were to be removed until the first 5 valid elements of all_items had been identified. The OP even mentioned the use of delete_if (aka reject!, not reject). I considered using a lazy enumerator, but there is no lazy reject!...
                        – Cary Swoveland
                        Nov 21 at 4:40










                      • ...Suppose all_times has 1,000 elements and the first 3 fail the test and the next five pass. An array of elements at offsets 3-7 of all_items is returned and all_items is unchanged. What use is that? The OP wants to use all_items with certain elements removed.
                        – Cary Swoveland
                        Nov 21 at 4:46












                      • @CarySwoveland based on return statement I deduced that the OP is just deleting elements because he wants to return the first five unrejected items, he doesn't care about the input. Moreover if deleting item was so important I assume deleting all the invalid items would have been priority instead of just rejecting to get the first five valid items.
                        – rubish
                        Nov 21 at 6:36










                      • @CarySwoveland sometimes refactoring doesn't simply mean rearranging the code for optimization or readability but identifying the underlying requirements and change the code to match requirements while optimizing and improving readability.
                        – rubish
                        Nov 21 at 6:38










                      • The last sentence of the OP's question unambiguous and is not the question you answered.
                        – Cary Swoveland
                        Nov 21 at 6:41
















                      1














                      You can use Enumerator::Lazy to achieve what you want:



                      all_items = [{"id" => "id01"},{"id" => "id02"},{"id" => "id03"},{"id" => "id04"},{"id" => "id05"},{"id" => "id06"},{"id" => "id07"},{"id" => "id08"},{"id" => "id09"},{"id" => "id10"}]
                      exclude_ids = ["id01","id02","id07"]
                      all_items.lazy.reject {|item| exclude_ids.include?(item['id']) }.first(5)





                      share|improve this answer





















                      • This is incorrect as it does not modify all_items. Instead, it returns an array containing the first 5 elements of all_items that are not contained in exclude_ids. The OP was quite specific that elements of all_items were to be removed until the first 5 valid elements of all_items had been identified. The OP even mentioned the use of delete_if (aka reject!, not reject). I considered using a lazy enumerator, but there is no lazy reject!...
                        – Cary Swoveland
                        Nov 21 at 4:40










                      • ...Suppose all_times has 1,000 elements and the first 3 fail the test and the next five pass. An array of elements at offsets 3-7 of all_items is returned and all_items is unchanged. What use is that? The OP wants to use all_items with certain elements removed.
                        – Cary Swoveland
                        Nov 21 at 4:46












                      • @CarySwoveland based on return statement I deduced that the OP is just deleting elements because he wants to return the first five unrejected items, he doesn't care about the input. Moreover if deleting item was so important I assume deleting all the invalid items would have been priority instead of just rejecting to get the first five valid items.
                        – rubish
                        Nov 21 at 6:36










                      • @CarySwoveland sometimes refactoring doesn't simply mean rearranging the code for optimization or readability but identifying the underlying requirements and change the code to match requirements while optimizing and improving readability.
                        – rubish
                        Nov 21 at 6:38










                      • The last sentence of the OP's question unambiguous and is not the question you answered.
                        – Cary Swoveland
                        Nov 21 at 6:41














                      1












                      1








                      1






                      You can use Enumerator::Lazy to achieve what you want:



                      all_items = [{"id" => "id01"},{"id" => "id02"},{"id" => "id03"},{"id" => "id04"},{"id" => "id05"},{"id" => "id06"},{"id" => "id07"},{"id" => "id08"},{"id" => "id09"},{"id" => "id10"}]
                      exclude_ids = ["id01","id02","id07"]
                      all_items.lazy.reject {|item| exclude_ids.include?(item['id']) }.first(5)





                      share|improve this answer












                      You can use Enumerator::Lazy to achieve what you want:



                      all_items = [{"id" => "id01"},{"id" => "id02"},{"id" => "id03"},{"id" => "id04"},{"id" => "id05"},{"id" => "id06"},{"id" => "id07"},{"id" => "id08"},{"id" => "id09"},{"id" => "id10"}]
                      exclude_ids = ["id01","id02","id07"]
                      all_items.lazy.reject {|item| exclude_ids.include?(item['id']) }.first(5)






                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Nov 20 at 9:13









                      rubish

                      10.2k33654




                      10.2k33654












                      • This is incorrect as it does not modify all_items. Instead, it returns an array containing the first 5 elements of all_items that are not contained in exclude_ids. The OP was quite specific that elements of all_items were to be removed until the first 5 valid elements of all_items had been identified. The OP even mentioned the use of delete_if (aka reject!, not reject). I considered using a lazy enumerator, but there is no lazy reject!...
                        – Cary Swoveland
                        Nov 21 at 4:40










                      • ...Suppose all_times has 1,000 elements and the first 3 fail the test and the next five pass. An array of elements at offsets 3-7 of all_items is returned and all_items is unchanged. What use is that? The OP wants to use all_items with certain elements removed.
                        – Cary Swoveland
                        Nov 21 at 4:46












                      • @CarySwoveland based on return statement I deduced that the OP is just deleting elements because he wants to return the first five unrejected items, he doesn't care about the input. Moreover if deleting item was so important I assume deleting all the invalid items would have been priority instead of just rejecting to get the first five valid items.
                        – rubish
                        Nov 21 at 6:36










                      • @CarySwoveland sometimes refactoring doesn't simply mean rearranging the code for optimization or readability but identifying the underlying requirements and change the code to match requirements while optimizing and improving readability.
                        – rubish
                        Nov 21 at 6:38










                      • The last sentence of the OP's question unambiguous and is not the question you answered.
                        – Cary Swoveland
                        Nov 21 at 6:41


















                      • This is incorrect as it does not modify all_items. Instead, it returns an array containing the first 5 elements of all_items that are not contained in exclude_ids. The OP was quite specific that elements of all_items were to be removed until the first 5 valid elements of all_items had been identified. The OP even mentioned the use of delete_if (aka reject!, not reject). I considered using a lazy enumerator, but there is no lazy reject!...
                        – Cary Swoveland
                        Nov 21 at 4:40










                      • ...Suppose all_times has 1,000 elements and the first 3 fail the test and the next five pass. An array of elements at offsets 3-7 of all_items is returned and all_items is unchanged. What use is that? The OP wants to use all_items with certain elements removed.
                        – Cary Swoveland
                        Nov 21 at 4:46












                      • @CarySwoveland based on return statement I deduced that the OP is just deleting elements because he wants to return the first five unrejected items, he doesn't care about the input. Moreover if deleting item was so important I assume deleting all the invalid items would have been priority instead of just rejecting to get the first five valid items.
                        – rubish
                        Nov 21 at 6:36










                      • @CarySwoveland sometimes refactoring doesn't simply mean rearranging the code for optimization or readability but identifying the underlying requirements and change the code to match requirements while optimizing and improving readability.
                        – rubish
                        Nov 21 at 6:38










                      • The last sentence of the OP's question unambiguous and is not the question you answered.
                        – Cary Swoveland
                        Nov 21 at 6:41
















                      This is incorrect as it does not modify all_items. Instead, it returns an array containing the first 5 elements of all_items that are not contained in exclude_ids. The OP was quite specific that elements of all_items were to be removed until the first 5 valid elements of all_items had been identified. The OP even mentioned the use of delete_if (aka reject!, not reject). I considered using a lazy enumerator, but there is no lazy reject!...
                      – Cary Swoveland
                      Nov 21 at 4:40




                      This is incorrect as it does not modify all_items. Instead, it returns an array containing the first 5 elements of all_items that are not contained in exclude_ids. The OP was quite specific that elements of all_items were to be removed until the first 5 valid elements of all_items had been identified. The OP even mentioned the use of delete_if (aka reject!, not reject). I considered using a lazy enumerator, but there is no lazy reject!...
                      – Cary Swoveland
                      Nov 21 at 4:40












                      ...Suppose all_times has 1,000 elements and the first 3 fail the test and the next five pass. An array of elements at offsets 3-7 of all_items is returned and all_items is unchanged. What use is that? The OP wants to use all_items with certain elements removed.
                      – Cary Swoveland
                      Nov 21 at 4:46






                      ...Suppose all_times has 1,000 elements and the first 3 fail the test and the next five pass. An array of elements at offsets 3-7 of all_items is returned and all_items is unchanged. What use is that? The OP wants to use all_items with certain elements removed.
                      – Cary Swoveland
                      Nov 21 at 4:46














                      @CarySwoveland based on return statement I deduced that the OP is just deleting elements because he wants to return the first five unrejected items, he doesn't care about the input. Moreover if deleting item was so important I assume deleting all the invalid items would have been priority instead of just rejecting to get the first five valid items.
                      – rubish
                      Nov 21 at 6:36




                      @CarySwoveland based on return statement I deduced that the OP is just deleting elements because he wants to return the first five unrejected items, he doesn't care about the input. Moreover if deleting item was so important I assume deleting all the invalid items would have been priority instead of just rejecting to get the first five valid items.
                      – rubish
                      Nov 21 at 6:36












                      @CarySwoveland sometimes refactoring doesn't simply mean rearranging the code for optimization or readability but identifying the underlying requirements and change the code to match requirements while optimizing and improving readability.
                      – rubish
                      Nov 21 at 6:38




                      @CarySwoveland sometimes refactoring doesn't simply mean rearranging the code for optimization or readability but identifying the underlying requirements and change the code to match requirements while optimizing and improving readability.
                      – rubish
                      Nov 21 at 6:38












                      The last sentence of the OP's question unambiguous and is not the question you answered.
                      – Cary Swoveland
                      Nov 21 at 6:41




                      The last sentence of the OP's question unambiguous and is not the question you answered.
                      – Cary Swoveland
                      Nov 21 at 6:41


















                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53385065%2fdelete-as-many-elements-from-the-beginning-of-an-array-that-match-a-value-until%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      "Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

                      Alcedinidae

                      Origin of the phrase “under your belt”?