2017-12-01 4 views
2

ich zwei unsortierte Arrays von Objekten zu vergleichen, zum Beispiel der folgende Code sollte true zurückgeben:Vergleichen unsortiert Arrays von Objekten in Javascript

compareObjs(
    [{ foo: 'foo', bar: 'bar' }, { baz: 'baz' }], 
    [{ baz: 'baz' }, { foo: 'foo', bar: 'bar' }] 
) 

Ich weiß, es gibt bereits viele Antworten über Arrays von Objekten zu vergleichen, aber ich habe nicht wirklich das klare gefunden, um die unsortierte Version von Arrays zu vergleichen.

+2

'Funktion compareObjs() {return true}' tun, dass extrapolted werden. * Warum * erwartest du, dass es wahr wird und wann nicht? – Bergi

+0

Ich erwarte, dass es wahr ist, weil die Länge der beiden Arrays die gleichen sind und sie die gleichen Objekte (gleiche Schlüssel und Werte) enthalten. Objektreferenzen spielen in diesem Fall keine Rolle. – Shota

+0

Mehrere Fragen hier fragt das gleiche. Check out: https://stackoverflow.com/questions/9191791/compare-arrays-of-objects-optimal-way und https://stackoverflow.com/questions/201183/how-to-determine- Gleichheit-für-zwei-javascript-objects/3198202 # 3198202 – xpqz

Antwort

0

Sie könnten jedes Objekt in einen String konvertieren, indem Sie JSON.stringify() verwenden. Dann sortiere diese Arrays. Und vergleichen Sie jedes Paar.

Wenn Sie dont't Meinung über es6:

let arr1 = [{ foo: 'foo', bar: 'bar' }, { baz: 'baz' }]; 
 
let arr2 = [{ baz: 'baz' }, { foo: 'foo', bar: 'bar' }]; 
 

 
const Compare = (arr1, arr2) => { 
 
    if (arr1.length != arr2.length) { 
 
    return false 
 
    } 
 

 
    let a1 = arr1.map(e => JSON.stringify(e)).sort() 
 
    let a2 = arr2.map(e => JSON.stringify(e)).sort() 
 
    
 
    return !a1.map((e, i) => e == a2[i]).includes(false) 
 
} 
 

 
console.log(Compare(arr1, arr2))

0

function givemeSanitizedObject(arr1) { 
 
    let obj = {} 
 
    arr1.forEach(function(element, index, array) { 
 
     obj = { 
 
     ...obj, 
 
     ...element, 
 
     } 
 
    }) 
 
    return obj 
 
} 
 

 
function compareObjs(arr1, arr2) { 
 
    let obj1 = givemeSanitizedObject(arr1) 
 
    let obj2 = givemeSanitizedObject(arr2) 
 

 
    for (var property in obj1) { 
 
     if (Object.hasOwnProperty(property)) { 
 
     if (obj1.property !== obj2.property) { 
 
      return false 
 
     } 
 
     } 
 
    } 
 
    return true 
 
} 
 

 
console.log(compareObjs(
 
    [{ 
 
    foo: 'foo', 
 
    bar: 'bar' 
 
    }, { 
 
    baz: 'baz' 
 
    }], [{ 
 
    baz: 'baz' 
 
    }, { 
 
    foo: 'foo', 
 
    bar: 'bar' 
 
    }] 
 
))

+0

Leider funktioniert das nicht: Sie behalten nicht die Struktur von jedem Objekt. Schau mal hier, es ist dein Code mit zwei deutlich unterschiedlichen Arrays: https://jsfiddle.net/1myf4cvk/ –

+0

Ja ich denke er hat einen anderen Anwendungsfall. Ich habe es jetzt gesehen. – stack26

+0

Sie sollten 'redude' anstelle von' forEach' in 'giveMeSanitisedObject' verwenden. Und Sie müssen '[property]' anstelle von '.property' verwenden. – Bergi

0

Ein grundlegender Ansatz zur Schleife durch alle Objekte eines der Arrays sein wird und sehen wenn Sie ähnliche Objekte im anderen Array finden können. Hier

ein Beispiel:

function compareArrays(arr1, arr2){ 
 
    if(arr1.length != arr2.length){ 
 
     return false; 
 
    } 
 

 
    for(var i = 0; i < arr1.length; i++){ 
 
     var value1 = arr1[i]; 
 
     var keys1 = Object.keys(value1); 
 
     var found = false; 
 
     for(var j = 0; j < arr2.length; j++){ 
 
      var value2 = arr2[j]; 
 
      var keys2 = Object.keys(value2); 
 
      if(keys1.length == keys2.length 
 
       && keys1.every(k => keys2.includes(k)) 
 
       && keys1.every(k => value1[k] == value2[k])){ 
 
       found = true; 
 
       break; 
 
      } 
 
     } 
 
     if(!found){ 
 
      return false; 
 
     } 
 
    } 
 
    
 
    return true; 
 
} 
 

 
var comp = compareArrays(
 
    [{ foo: 'foo', bar: 'bar' }, { baz: 'baz'}], 
 
    [{ baz: 'baz' }, { foo: 'foo', bar: 'bar'}] 
 
); 
 

 
console.log(comp);

0

Sie könnten eine Hash-Tabelle verwenden und überprüfen, ob die proprties und Werte gleich sind. Es funktioniert mit den angegebenen Typen.

function compareArrays(array1, array2) { 
 
    var hash = {}; 
 

 
    if (array1.length !== array2.length) { 
 
     return false; 
 
    } 
 

 
    array1.forEach(function (o) { 
 
     var keys = Object.keys(o).sort(), 
 
      key = keys.join('|'), 
 
      value = keys.map(function (k) { return o[k]; }).join('|'); 
 

 
     hash[key] = hash[key] || {}; 
 
     hash[key][value] = (hash[key][value] || 0) + 1; 
 
    }); 
 

 
    return array2.every(function (o) { 
 
     var keys = Object.keys(o).sort(), 
 
      key = keys.join('|'), 
 
      value = keys.map(function (k) { return o[k]; }).join('|'); 
 

 
     return hash[key] && hash[key][value] && hash[key][value]--; 
 
    }); 
 
} 
 

 
console.log(compareArrays([{ foo: 'foo', bar: 'bar' }, { baz: 'baz' }], [{ baz: 'baz' }, { foo: 'foo', bar: 'bar' }])); 
 
console.log(compareArrays([{ foo: 'foo', bar: 'bar' }, { baz: 'baz' }, { baz: 'baz' }], [{ baz: 'baz' }, { foo: 'foo', bar: 'bar' }])); 
 
console.log(compareArrays([{ foo: 'foo', bar: 'bar' }, { baz: 'baz' }, { foo: 'baz' }], [{ baz: 'baz' }, { foo: 'foo', bar: 'bar' }])); 
 
console.log(compareArrays([{ foo: 'foo', bar: 'bar' }, { baz: 'baz' }, { foo: 'baz' }], [{ baz: 'baz' }, { foo: 'foo', bar: 'bar' }, { foo: 42 }]));

+0

Es funktioniert nicht mit Objekten, deren Schlüssel oder Werte ein '|' though enthalten. Oder mit Werten, die überhaupt keine Strings sind. Ich würde empfehlen, 'JSON.stringify()' stattdessen für die sortierten Arrays von Schlüsseln und Werten zu verwenden. – Bergi

+0

Sie können auch vereinfachen, indem Sie 'key' und' value' verketten, anstatt die Nachschlagetabelle zu verschachteln. – Bergi

0

Sie können so etwas wie unten versuchen

  • in jedem Array mehrere Objekte reduzieren in einem
  • Sortierschlüssel und bauen ein 2D-Array oder bauen ein neues Objekt
  • Vergleichen Sie die beiden neu erstellten Datenstrukturen (2D-Arrays/Objekte)

Dies kann auf eine beliebige Anzahl von Arrays

const arr1 = [{ foo: 'foo', bar: 'bar' }, { baz: 'baz' }]; 
 
const arr2 = [{ baz: 'baz' }, { foo: 'foo', bar: 'bar' }]; 
 

 
// Method that sorts the object keys and builds a new object 
 
// sortObj = (obj) => 
 
// Object.keys(obj).sort().reduce((a, b) => {a[b] = obj[b]; return a}, {}) 
 
    
 
// Method that sorts keys and builds a 2D array 
 
sortObj = (obj) => 
 
    Object.keys(obj).sort().map((key) => [key, obj[key]]) 
 

 
compareObj = (arr1, arr2) => { 
 
    if(arr1.length !== arr2.length) 
 
    return false; 
 
    
 
    // 1st array reduce 
 
    const reduceArr1 = arr1.reduce((a, b) => ({...a, ...b}), {}); 
 
    
 
    // 2nd array reduce 
 
    const reduceArr2 = arr2.reduce((a, b) => ({...a, ...b}), {}); 
 
    
 
    // Comparing the sortedObjects 
 
    return JSON.stringify(sortObj(reduceArr1)) === JSON.stringify(sortObj(reduceArr2)) 
 
} 
 

 
console.log(compareObj(arr1, arr2))

Verwandte Themen