数组相等:重复问题

时间:2016-09-24 17:37:22

标签: javascript arrays

我已经建立了自己的阵列平等''''''''函数,当数组中的所有值都是唯一的时,它按预期工作:

示例: (工作)

var
   a = [1, 2, 3, ["a", "b"]],
   b = [1, 2, 3, ["a", "b"]];

arrayEquals(a, b); /* returns: [true, true, true, [true, true]] */

但是,如果存在重复值,则最终结果会严重损坏:

示例: (非工作)

在此示例中, 1 在第一个数组中存在两次。问题是第二个 1 会返回第二个数组的第一个 1 作为匹配,即使 {{ 1}} 已经在第一个数组的前一个 1 之前就已经匹配了。

1

问题:

有没有办法安全地删除或避免检查匹配的元素,以便更改结果?

我尝试过的事情:

1)我试图以下面的方式删除两个阵列中存在的元素,但不幸的是它没有任何好处:

示例:

var
   a = [1, 1, 2],
   b = [1, 2, 2];

arrayEquals(a, b); /* returns: [true, false, false] */
                   /* should return: [true, false, true] */

2)我已经尝试过 if (eachA === eachB) { a.splice.call(index, 1); // Removing the matched elements b.splice.call(jindex, 1); // Removing the matched elements result[index] = true; } 以及 if (eachA === eachB && !result[index] && !result[jindex]) result[index] = true; 和< strong> result[index] 已经为真,这意味着一个数组中的值已与另一个数组中的值匹配。

代码:

&#13;
&#13;
result[jindex]
&#13;
&#13;
&#13;

检查程序:

/* Main function */
function arrayEquals(a, b, result) {
  return (a === b && a !== null) || (a.length === b.length &&
    (function check(a, b, result) {
      /* Check equality between 'a' and 'b' arrays */
      a.forEach(function(eachA, index) {
        b.forEach(function(eachB, jindex) {
          if (eachA === eachB) result[index] = true;
          /* Handle objects */
          else if (isObject(eachA) && isObject(eachB))
            result[index] = objectEquals(a, b);
          /* Handle arrays */
          else if (isArray(eachA) && isArray(eachB))
            check(eachA, eachB, (result[index] = []));
          /* Turn all 'undefined' to 'false' */
          else result[index] = (!!result[index]) ? true : false;
        });
      });
      return result;
    })(a, b, (result = [])));
}

/* Usage */
var
  a = [1, 1, 2, ["a", "b"]],
  b = [1, 2, 2, ["a", "b"]];

console.log(arrayEquals(a, b)); /* returns: [true, true, true, [true, true]] */
                                /* should return: [true, false, true, [true, true]] */

/* Supplementary functions */
function isArray(array) {return !!array && array.constructor === Array;}

function isObject(object) {return !!object && object.constructor === Object;}
  • 对于第一个数组的每个索引,我们检查第二个数组的所有索引,逐个找到匹配。

  • 对于第一个数组, var a = [1, 1, 2], b = [1, 2, 2]; (在索引0处) 1 (在索引0处)第二个数组。

  • 然后对于第一个数组, 1 (在索引1处)与第二个数组的任何索引都不匹配(索引0处的1不算数,因为我们之前找到了匹配项)

  • 最后,对于第一个数组, 1 (在索引2处)匹配 2 第二个数组的(在索引1处)。结果:[true,false,true] | 不等于

要点:

  • 每个索引必须匹配,可能是相同的索引或其他索引。

  • 如果第二个数组的一个索引用作第一个数组的先前索引的匹配项,则不能再将其用作匹配项。

  • 必须在另一个要使用的索引处再次存在相同的元素。

图片: The procedure

8 个答案:

答案 0 :(得分:1)

如果保证您的阵列具有相同的结构,您可以执行以下操作;

&#13;
&#13;
var a = [1, 1, 2, ["a", "b"]],
    b = [1, 2, 2, ["a", "b"]];

function arrayCompare(a,b){
 return a.map((e,i) => Array.isArray(e) ? arrayCompare(e, b[i])
                                        : e === b[i]);
}

console.log(arrayCompare(a,b))
&#13;
&#13;
&#13;

答案 1 :(得分:0)

  

两个数组应具有相同的长度和完全相同的元素   在任何顺序中。

您可以使用返回数组的Array.prototype.filter().length

&#13;
&#13;
var a = [1, 1, 2],
  b = [1, 2, 2],
  c = [1, 2, 1],
  d = [2, 1, 3],
  e = [2, 2, 1],
  f = [2, 1, 2];
    

var compare = (a, b) => 
      a.map(el =>
        b.filter(item => item === el).length ===
        a.filter(item => item === el).length
      );

console.log(compare(a, b), compare(c, d), compare(e, f))
&#13;
&#13;
&#13;

答案 2 :(得分:0)

而不是两个foreach循环只使用一个并与其他元素的相同索引进行比较。请查看下面的代码段。

&#13;
&#13;
/* Main function */
function arrayEquals(a, b, result) {
  return (a === b && a !== null) || (a.length === b.length &&
    (function check(a, b, result) {
      /* Check equality between 'a' and 'b' arrays */
      a.forEach(function(eachA, index) {
        if (eachA === b[index]) result[index] = true;
          /* Handle objects */
          else if (isObject(eachA) && isObject(b[index]))
            result[index] = objectEquals(a, b);
          /* Handle arrays */
          else if (isArray(eachA) && isArray( b[index]))
            check(eachA,  b[index], (result[index] = []));
          /* Turn all 'undefined' to 'false' */
          else result[index] = (!!result[index]) ? true : false;
      });
      return result;
    })(a, b, (result = [])));
}

/* Usage */
var
  a = [1, 1, 2, ["a", "b"]],
  b = [1, 2, 2, ["a", "b"]];

console.log(arrayEquals(a, b)); /* returns: [true, true, true, [true, true]] */
                                /* should return: [true, false, true, [true, true]] */

/* Supplementary functions */
function isArray(array) {return !!array && array.constructor === Array;}

function isObject(object) {return !!object && object.constructor === Object;}
&#13;
&#13;
&#13;

答案 3 :(得分:0)

这应该有用......

&#13;
&#13;
var
   a = [1, 2, 3, ["a", "b"]],
   b = [1, 2, 3, ["a", "b"]];

var
   c = [1, 1, 2, ["a", "b"]],
   d = [1, 2, 2, ["a", "b"]];

function arrayEquals(a, b) {
  if (a.length !== b.length) return false
  return a.map(function(el, i) {
    if (typeof a[i] === 'object' && a[i] instanceof Array) return arrayEquals(a[i], b[i])
    return a[i] === b[i] ? true : false
  })
}

console.log(arrayEquals(a, b))
console.log(arrayEquals(c, d))
&#13;
&#13;
&#13;

答案 4 :(得分:0)

你太复杂了。您只需要map最长的数组,并且对于每个索引,比较两个元素(如果有的话)是否为数组。如果是,则使用递归,否则正常比较。

function arrayCompare(arr1, arr2) {
  if(arr1.length < arr2.length) return arrayCompare(arr2, arr1);
  return arr1.map(function(item, idx) {
    if (idx >= arr2.length) return false;
    var b = Array.isArray(item) && Array.isArray(arr2[idx]);
    return (b ? arrayCompare : Object.is)(item, arr2[idx]);
  });
}
console.log(JSON.stringify(arrayCompare([1, 2, 3, ["a", "b"]], [1, 2, 3, ["a", "b"]])));
console.log(JSON.stringify(arrayCompare([1, 1, 2, ["a", "b"]], [1, 2, 2, ["a", "b"]])));
console.log(JSON.stringify(arrayCompare([1, 1, 2, 3], [1, 2, 2, ["a", "b"]])));
console.log(JSON.stringify(arrayCompare([1], [1, 2, 2, ["a", "b"]])));

答案 5 :(得分:0)

这是一个完全递归的函数,用于比较数组:

select cast(orig_time as time(0))

答案 6 :(得分:0)

也许,有比以下更好的方法,但以下仍然可以完成工作。

解决方案的作用:

基本上,以下操作是将 eachA eachB 的值(如果它们相等)更改为某些正则表达式

据我所知,两个正则表达式不能相等,所以在其中一个数组中已经存在相同正则表达式的狂野场景中,它会导致 false 无论如何。

毕竟谁把一个RegExp放在一个数组中并且碰巧想检查那个数组是否等于另一个?!

<强>解决方案:

if (eachA === eachB) {
   result[index] = true;
   a[index] = b[jindex] = /RegExp/;
}

此外:

为了避免任何意外,必须打破内部 forEach 循环,以便在找到匹配项时,它会直接转到下一个字符。因此,我们将 forEch **更改为** for ,然后将其分解。

if (eachA === eachB) {
   result[index] = true;
   a[index] = b[jindex] = /RegExp/;
   break;
}

<强>代码:

&#13;
&#13;
/* Main function */
function arrayEquals(a, b, result) {
  return (a === b && a !== null) || (a.length === b.length &&
    (function check(a, b, result) {
      /* Check equality between 'a' and 'b' arrays */
      a.forEach(function(eachA, index) {
        for (var jindex = 0, eachB = b[jindex]; jindex < b.length;
             jindex++, eachB = b[jindex]) {
          if (eachA === eachB) result[index] = true,
            a[index] = b[jindex] = /RegExp/, break;
          }
          /* Handle objects */
          else if (isObject(eachA) && isObject(eachB))
            result[index] = objectEquals(a, b);
          /* Handle arrays */
          else if (isArray(eachA) && isArray(eachB))
            check(eachA, eachB, (result[index] = []));
          /* Turn all 'undefined' to 'false' */
          else result[index] = (!!result[index]) ? true : false;
        }
      });
      return result;
    })(a, b, (result = [])));
}

/* Usage */
var
  a = [1, 2, 2, ["a", "b"]],
  b = [1, 2, 2, ["a", "b"]];

console.log(JSON.stringify(arrayEquals(a, b)));

/* Supplementary functions */
function isArray(array) {return !!array && array.constructor === Array;}

function isObject(object) {return !!object && object.constructor === Object;}
&#13;
&#13;
&#13;

答案 7 :(得分:0)

我正在做C#和C ++,而不是JavaScript,所以我不能给你工作代码。但是这里有一些pseudecode可以让你知道它是如何工作的 这是写在我的脑海里,用手机打字(糟糕的工作)和未经测试。希望这对你有用!请为任何拼写错误道歉,这可能是德国自动更正造成的。

bool Compare (array a, array b, ref array result)
{
  Check whether arrays existiert and length is equal, return false if not;

  array<bool> b_used = new array(length (b));
  for (int indexa = 0 to length(a)-1)
  {
    if (a is value or object)
    { // compare against every b
      result[indexa] = false;
      for (int indexb = 0 to length(b)-1)
      {
        if (b_used[indexb])
          continue;  // this is the key: don't use an index twice!

        if (a[indexa] == b[indexb])
        {
          result[indexa] = true;
          b_used[indexb] = true;
          break;
        }
      }
    }
    Else if (array)
    ...
    And so on.

请注意,内部数组是单独处理的,不与外部数组的值进行比较。