ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
From: cary@swoveland.com
To: ruby-core@ruby-lang.org
Subject: [ruby-core:72135] [Ruby trunk - Feature #11815] Proposal for method `Array#difference`
Date: Tue, 15 Dec 2015 05:15:20 +0000	[thread overview]
Message-ID: <redmine.journal-55546.20151215051519.bf1e0580dae5dfab@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-11815.20151214082709@ruby-lang.org

Issue #11815 has been updated by Cary Swoveland.


Matz, alas, I cannot offer one. You see, Ruby--coding generally--is just a hobby for me. I spend a fair bit of time answering Ruby questions on SO and would have reached for this method on many occasions had it been available. Perhaps readers with development experience (everybody but me?) could reflect on whether this method would have been useful in projects they've worked on.

----------------------------------------
Feature #11815: Proposal for method `Array#difference`
https://bugs.ruby-lang.org/issues/11815#change-55546

* Author: Cary Swoveland
* Status: Open
* Priority: Normal
* Assignee: 
----------------------------------------
I propose that a method `Array#difference` be added to the Ruby core. It is similar to [Array#-](http://ruby-doc.org/core-2.2.0/Array.html#method-i-2D) but for each element of the (array) argument it remove only one matching element from the receiver. For example:

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

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

As you see, `a` contains three `2`'s and `b` `1`, so the first `3-1 #=> 2` `2`'s in `a` have been removed from `a` in constructing `c`. When `b` contains as least as many instances of an element as does `a`, `c` contains no instances of that element. 

It could be implemented as follows:

     class Array
       def difference(other)
         dup.tap do |cpy|
           other.each do |e|
             ndx = cpy.index(e)
             cpy.delete_at(ndx) if ndx
            end
          end
        end
      end

Here are a few examples of its use:

*Identify an array's non-unique elements*

      a = [1,3,2,4,3,4]
      u = a.uniq          #=> [1, 2, 3, 4]
      u - a.difference(u) #=> [1, 2]

*Determine if two words of the same size are anagrams of each other*

      w1, w2 = "stop", "pots"
      w1.chars.difference(w2.chars).empty?
        #=> true

*Identify a maximal number of 1-1 matches between the elements of two arrays and return an array of all elements from both arrays that were not matched*

      a = [1, 2, 4, 2, 1, 7, 4, 2, 9] 
      b = [4, 7, 3, 2, 2, 7] 
      a.difference(b).concat(b.difference(a))
        # => [1, 1, 4, 2, 9, 3, 7] 
  
To remove elements from `a` starting at the end (rather the beginning) of `a`:

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

    a.reverse.difference(b).reverse #=> [1,2,3,2]

`Array#difference!` could be defined in the obvious way.



-- 
https://bugs.ruby-lang.org/

  parent reply	other threads:[~2015-12-15  4:43 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <redmine.issue-11815.20151214082709@ruby-lang.org>
2015-12-14  8:27 ` [ruby-core:72107] [Ruby trunk - Feature #11815] [Open] Proposal for method `Array#difference` cary
2015-12-14  9:38 ` [ruby-core:72111] [Ruby trunk - Feature #11815] " cary
2015-12-15  4:33 ` [ruby-core:72132] " matz
2015-12-15  5:15 ` cary [this message]
2015-12-15  6:56 ` [ruby-core:72138] " cary
2015-12-15  7:02 ` [ruby-core:72139] " cary
2015-12-15  8:01 ` [ruby-core:72140] " duerst
2015-12-15  8:47 ` [ruby-core:72141] " cary
2015-12-15 12:27 ` [ruby-core:72143] " 6ftdan
2015-12-15 17:37 ` [ruby-core:72151] " cary
2015-12-15 17:52 ` [ruby-core:72154] " 6ftdan
2015-12-18  3:48 ` [ruby-core:72235] " rp.beltran
2015-12-18 10:17 ` [ruby-core:72363] " duerst
2015-12-19 19:22 ` [ruby-core:72392] " cary
2016-08-19 22:43 ` [ruby-core:76988] [Ruby trunk Feature#11815] " cary
2016-09-15 16:43 ` [ruby-core:77285] " cary
2018-09-29 14:14 ` [ruby-core:89215] " florian.ebeling
2018-09-30 12:16 ` [ruby-core:89219] " florian.ebeling
2018-10-05 20:04 ` [ruby-core:89290] " florian.ebeling

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.ruby-lang.org/en/community/mailing-lists/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=redmine.journal-55546.20151215051519.bf1e0580dae5dfab@ruby-lang.org \
    --to=ruby-core@ruby-lang.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).