37539

Compare arrays of objects independent of the order

Question:

I have 2 arrays of objects and I have to compare them, but the order of the objects <strong>DOES NOT</strong> matter. I can't sort them because I won't have their keys' names because the functions must be generic. The only information that I'll have about the array is that both array's objects have the same amount of keys and those keys have the same name. So the array1 must contain the same objects as the array2.

var array1 = [{"key1":"Banana", "key2":"Yammy"}, {"key1":"Broccoli", "key2":"Ew"}]; var array2 = [{"key1":"Broccoli", "key2":"Ew"}, {"key1":"Banana", "key2":"Yammy"}];

In the example, array1 must be equal array2. I tryed to use the chai .eql() method but it didn't work.

Answer1:

You can array#join each value of the object on an separator and then generate a new array of string and then compare each values using array#every and array#includes

<pre class="snippet-code-js lang-js prettyprint-override">var array1 = [{"key1":"Banana", "key2":"Yammy"}, {"key1":"Broccoli", "key2":"Ew"}]; array2 = [{"key1":"Broccoli", "key2":"Ew"}, {"key1":"Banana", "key2":"Yammy"}]; values = (o) => Object.keys(o).sort().map(k => o[k]).join('|'), mapped1 = array1.map(o => values(o)), mapped2 = array2.map(o => values(o)); var res = mapped1.every(v => mapped2.includes(v)); console.log(res);

Answer2:

For a solution that requires the arrays to have an equal number of elements, does not require keys to not contain a certain delimiter, requires both keys and (string) values to be the same, and runs in <em>O(nlogn)</em> instead of <em>O(n²)</em>:

<pre class="snippet-code-js lang-js prettyprint-override">function equalArrays(a, b) { if (a.length !== b.length) return false; const ser = o => JSON.stringify(Object.keys(o).sort().map( k => [k, o[k]] )); a = new Set(a.map(ser)); return b.every( o => a.has(ser(o)) ); } // Example var array1 = [{"key1":"Banana", "key2":"Yammy"}, {"key1":"Broccoli", "key2":"Ew"}]; var array2 = [{"key1":"Broccoli", "key2":"Ew"}, {"key1":"Banana", "key2":"Yammy"}]; console.log(equalArrays(array1, array2)); // true // Example with different key name var array1 = [{"key0":"Banana", "key2":"Yammy"}, {"key1":"Broccoli", "key2":"Ew"}]; var array2 = [{"key1":"Broccoli", "key2":"Ew"}, {"key1":"Banana", "key2":"Yammy"}]; console.log(equalArrays(array1, array2)); // false

Answer3:

You can do something like following:

For each object in each array you can calc its representation:

arr1.forEach( (obj) => { obj.representation = ''; for (let key of Object.keys(obj)) { obj.representation += obj[key]; } }

Same for arr2

now you can sort both arrays by representation for example and then compare.

To sort do the following:

arr1.sort( (a,b) => { return a.representation > b.representation } ); arr2.sort( (a,b) => { return a.representation > b.representation } );

After sorting you can compare both arrays

let equal = arr1.every( (el, i) => arr2[i]===el );

Recommend

  • Using PowerShell to decrypt a Python encrypted String
  • Retain fixtures with multiple adapters per Ember environment
  • How do you stub fetch api request
  • Best way to make text look fading away
  • How to turn off JSHint error?
  • sinon stub with es6-promisified object
  • Common Lisp: Getting the documentation string of a macro
  • React Redux async action testing
  • Zapier timeout error on test
  • Cannot run protractor scripts using code generated by Appium for IOS it says that findelement is not
  • modifying text of a div using dojo
  • C++11 std::threads and waiting for threads to finish
  • Ordered http request parameters
  • My code is looping once more than I want it to, I suspect something is wrong with my getchar stateme
  • TypeScript to JavaScript transpiler for Angular2
  • regex: Why this negative lookahead doesn't work?
  • How to make an elasticsearch query that filters on the maximum value of a field?
  • How to preserve line breaks but have text-align:justify?
  • Conditional in Rails partial depending on the context page?
  • TFS express error: The working folder C:\\LocalFolder is already in use
  • reduce/reduce conflicts using ocamlyacc
  • How to write string.Contains(someText) in expression Tree
  • How to get the index of element in the List in c#
  • Rails AREL .where statement
  • R convert summary result (statistics with all dataframe columns) into dataframe
  • Implicit joins and Where in Doctrine - how?
  • D3 get axis values on zoom event
  • Jetty Server not starting: Unable to establish loopback connection
  • Django: Count of Group Elements
  • How to check if every primary key value is being referenced as foreign key in another table
  • How to handle AllServersUnavailable Exception
  • Trying to switch camera back to front but getting exception
  • How to get next/previous record number?
  • R: gsub and capture
  • jqPlot EnhancedLegendRenderer plugin does not toggle series for Pie charts
  • Comma separated Values
  • Free memory of cv::Mat loaded using FileStorage API
  • Angular 2 constructor injection vs direct access
  • Programmatically clearing map cache
  • How to load view controller without button in storyboard?