Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!eu.feeder.erje.net!weretis.net!feeder1.news.weretis.net!news.solani.org!.POSTED!not-for-mail From: Thomas 'PointedEars' Lahn Newsgroups: comp.lang.javascript Subject: Re: Difference between two arrays Date: Tue, 27 May 2014 17:41:54 +0200 Organization: PointedEars Software (PES) Lines: 60 Message-ID: <73754615.KVtT6colLE@PointedEars.de> References: <0.e9255226716292b2ac8f.20140527134102BST.87lhtne6n5.fsf@bsb.me.uk> Reply-To: Thomas 'PointedEars' Lahn Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8Bit X-Trace: solani.org 1401205317 20930 eJwNycERACEIA8CWxAC5dhRI/yWcv53ZQFoWPSM9FFqNfZ98T4HscVEH58UsGi98DE3VbOWHHybyEY8= (27 May 2014 15:41:57 GMT) X-Complaints-To: abuse@news.solani.org NNTP-Posting-Date: Tue, 27 May 2014 15:41:57 +0000 (UTC) User-Agent: KNode/4.12.4 X-User-ID: eJwNy8kRwDAIBLCWuBZDORjP9l9Cor/gqbknEhkg2FmQbNToPMI8rTS6zT1cNsY4zVciysEe36eKc++w8d8PHtYUew== Cancel-Lock: sha1:/20Jj0DldL/RBxepinEi7J+TFIs= X-NNTP-Posting-Host: eJwVx8kRwDAIA8CWzCHhlBOw1X8JmexvETROJcGEoPKu4PSFzLXjpacdkXvd9lnnCdTf8pM1+gAXYRDi Xref: csiph.com comp.lang.javascript:24441 Ben Bacarisse wrote: > Andrew Poulos writes: >> If I have two "simple" arrays and I need to create a third array of >> elements that are only in one of the arrays. I found this >> >> Array.prototype.difference = function (a) { >> return this.filter(function (i) { >> return !(a.indexOf(i) > -1); >> }); >> }; > > […] > Anyway, the call constructs an array the includes only those elements of > "this" that can't be found in "a". > > Depending on lots of unknowns, it may be faster to invert the arrays. > I.e. to show the presence of element x by setting a[x] to some specific > value, rather than have some index i at which a[i] === x. You can not simply invert arrays in ECMAScript implementations. Arrays are objects, therefore keys are properties of an object. Values whose string representation is the same as a property of the object can overwrite built- in properties. > This makes testing for membership fast, but at the expense of other > things. In particular, unless the implementation is clever, a very wide > range of values can result is very large inverted arrays. If the values can be unambiguously converted to String, using Object instances with empty prototype chain is recommended. The property name would be the string representation of the value. Otherwise, a Map implementation such as those in JSX:map.js could/should be used. > The symmetric difference then looks like this: > > Array.prototype.symDiff = function (a) { > var count = []; > this.forEach(function (e) { count[e] = 1; }); > a.forEach(function (e) { count[e] = (count[e] || 0) | 2; }); > var result = []; > count.forEach(function (e, i) { if (e !== 3) result.push(i); }); In most cases, you want to use a “for … in …” loop instead of Array.prototype.forEach(), particularly where speed is of the essence. Not only can you save several function calls this way, you can also avoid unnecessary iterations with sparse arrays. It should be tested before whether array indexes are enumerable (per ES and in recent implementations they are), and potentially augmented prototypes have to be considered. Also, forEach() operates *only* on array indexes. Therefore, the approach above will fail if values are not array indexes. -- PointedEars FAQ: | SVN: Twitter: @PointedEars2 | ES Matrix: Please do not Cc: me. / Bitte keine Kopien per E-Mail.