【问题标题】:Compare arrays of objects independent of the order独立于顺序比较对象数组
【发布时间】:2017-10-31 17:34:41
【问题描述】:

我有 2 个对象数组,我必须比较它们,但是对象的顺序 很重要。我无法对它们进行排序,因为我没有它们的键名,因为函数必须是通用的。我将拥有的关于数组的唯一信息是两个数组的对象具有相同数量的键并且这些键具有相同的名称。所以 array1 必须包含与 array2 相同的对象。

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

在示例中,array1 必须等于 array2。 我尝试使用 chai .eql() 方法,但没有成功。

【问题讨论】:

  • 我正在使用 Chai。
  • “比较它们”是什么意思?您只需要知道它们是否相同吗?布尔响应?
  • 你的问题不清楚
  • 所有值都是字符串类型吗?
  • 所有值都是字符串。

标签: javascript arrays json chai unordered


【解决方案1】:

以下解决方案:

  • 将验证数组是否具有相等数量的元素
  • 不对键施加限制(至于包含一定的分隔符)
  • 要求键和(字符串)值相同
  • 时间复杂度为 O(nlogn)(而不是 O(n²) 作为这里的一些其他解决方案)

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

【讨论】:

    【解决方案2】:

    您可以将array#join对象的每个值放在一个分隔符上,然后生成一个新的字符串数组,然后使用array#everyarray#includes比较每个值

    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);

    【讨论】:

    • 当一个数组的条目比另一个数组多时,当一个键具有管道符号时,当对象具有不同的键时,这可能会失败...
    • 它就像一个魅力。有一种简单的方法可以打印不匹配的对象数组吗?例如,如果其中一个数组不是“香蕉”,而是“香蕉”。
    • @trincot,我在比较对象之前验证数组的长度。
    • 错误结果示例:先将"key1"更改为"key0":结果仍然为真。或者,删除"key2": "Yammy" 并将"Banana" 更改为"Banana|Yammy":结果仍然正确。
    • @trincot 你在这两个帐户上都是正确的,但问题提到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.
    【解决方案3】:

    您可以执行以下操作:

    对于每个数组中的每个对象,您都可以计算其表示:

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

    arr2 也一样

    现在您可以通过表示来对两个数组进行排序,然后进行比较。

    要排序,请执行以下操作:

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

    排序后可以比较两个数组

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多