检查数组是否具有另一个数组的键值对

时间:2018-01-20 01:58:07

标签: javascript arrays object

我有两组数组:

var a = [1, 2, {a: 1, b:2}, 3];
var b = [1, {a: 1, b: 2}, 3};

如果数组a具有ALL(EXACT)数组b(包括对象)的属性和值,那么它将使计数增加1.否则,如果数组a只有一些属性且某些值不匹配,则将退出,什么都不做。

举个例子:

var a = [1, 2, {a: 1, b:2}, 3];
var b = [1, {a: 1, b: 2}, 3}; 
// return true / count++

var a = [1, 2, 3, {a: 1, b: 4}];
var b = [1, 2, {a: 1, b: 6}, 3];
return false / no count

首先是我的计划:

for(var i = 0; i < mainArr[i]; i++){
if(arr.includes(mainArr[i])){
      count++;
    }

if(typeof(mainArr[i]) === 'object' && typeof(arr[i]) === 'object'){
      for(var mainArrProp in mainArr[i]){
        for(var arrProp in arr[i]){
          if(arr[i].hasOwnProperty(mainArrProp) && arr[i][arrProp] === mainArr[i][mainArrProp]){
            count++;
          }
        }
      }
    }
}

有什么方法可以解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

如果你可以使用es6,你可以利用一些新的方法来做一个(相对)短的函数来做到这一点。具体来说,我们将使用数组includeseverysome方法来检查浅层对象的相等性:

&#13;
&#13;
function getIncrementValue(set, subset) {
    for (let item of subset) {
        if (typeof item === "object") {
            // Special case if looking at an object. I am assuming object is always shallow.
            if (!set.some(otherItem => typeof otherItem === "object" && Object.keys(otherItem).length === Object.keys(item).length && Object.keys(otherItem).every(key => (key in item) && item[key] === otherItem[key]))) return 0;
        } else {
            if (!set.includes(item)) return 0;
        }
    }
    
    return 1;
}

// So for your arrays:

var a1 = [1, 2, {a: 1, b:2}, 3];
var b1 = [1, {a: 1, b: 2}, 3]; 
// return true / count++

var a2 = [1, 2, 3, {a: 1, b: 4}];
var b2 = [1, 2, {a: 1, b: 6}, 3];
// return false / no count

console.log(getIncrementValue(a1, b1)) // returns 1;
console.log(getIncrementValue(a2, b2)) // returns 0;
&#13;
&#13;
&#13;

除了用于检查对象相等性的一条长行之外,这非常简单。但所有这一切都是:

如果set的某些元素没有:

  • 是一个对象,
  • 元素和我们当前的项目具有相同数量的键,
  • 该元素的每个键都是我们当前项目的键,
  • 每个键的值都相同

然后返回1.

答案 1 :(得分:0)

你遵循完全错误的方式,在你的情况下你不需要使用常规count++,如果arrayB中不存在arrayA中的任何值,你应该更好地减少1并返回。我重写了方法并解释了每一行,我想,应该清楚发生了什么。我也注意到,你在ES5中写,但你也使用includes(),这是一个ES6功能,很高兴知道。我已将includes()留在我的实施中。如果第一个数组中的所有值都存在于第二个数组中,则我的方法返回1,否则返回0。这是:

function test(a, b) {
  var count = 1,
      /* "aValues" will contain both single numbers and object values from "a" array */
      aValues = createHomogeneousArray(a),
      /* "bValues" will contain both single numbers and object values from "b" array */
      bValues = createHomogeneousArray(b);
  /* Check does each value of "aValues" exists in "bValues" array, if not - return "count--" (will be equal to "0") */
  aValues.forEach(function(item) {
    if (!bValues.includes(item)) {
      return count--
    }
  });
  
  /* If nothing was returned yet, return count (is equal to "1") */
  return count;
}

function createHomogeneousArray(arr) {
  var finalArr = [];
  /* Iterate through array */
  arr.forEach(function(item) {
    /* Check is object */
    if (typeof item === 'object') {
      /* If object - get all values of this object as array */
      var arrOfObjValues = Object.values(item);
      /* Iterate through this array with object values */
      arrOfObjValues.forEach(function(value) {
        /* Push each value of above array to the "finalArr" array, which contains ALL values of the array, passed to this function */
        finalArr.push(value);
      });
    /* Check is number */
    } else if (typeof item === 'number') {
      /* Push all regular numbers to final array */
      finalArr.push(item);
    }
  });
  /* Return "finalArr" array */
  return finalArr;
}

console.log(test(
  [1, 2, {a: 1, b:2}, 3],
  [1, {a: 1, b: 2}, 3]
))

console.log(test(
  [1, 2, 3, {a: 1, b: 4}],
  [1, 2, {a: 1, b: 6}, 3]
))

不要害怕代码的大小,如果没有评论它会小得多:

function test(a, b) {
  var count = 1,
      aValues = createHomogeneousArray(a),
      bValues = createHomogeneousArray(b);
  aValues.forEach(function(item) {
    if (!bValues.includes(item)) {
      return count--
    }
  });
  return count;
}

function createHomogeneousArray(arr) {
  var finalArr = [];
  arr.forEach(function(item) {
    if (typeof item === 'object') {
      var arrOfObjValues = Object.values(item);
      arrOfObjValues.forEach(function(value) {
        finalArr.push(value);
      });
    } else if (typeof item === 'number') {
      finalArr.push(item);
    }
  });
  return finalArr;
}

console.log(test(
  [1, 2, {a: 1, b:2}, 3],
  [1, {a: 1, b: 2}, 3]
))

console.log(test(
  [1, 2, 3, {a: 1, b: 4}],
  [1, 2, {a: 1, b: 6}, 3]
))