在对象数组中查找对象的行踪

时间:2017-10-05 16:46:21

标签: javascript arrays object

function whatIsInAName(collection, source) {
  var result = [];
  var arr1 = Object.keys(source);
  console.log(arr1);

  for (var i = 0; i < collection.length; i++) {
    for (var j = 0; j < arr1.length; j++) {
      if (collection[i].hasOwnProperty(arr1[j]) === false) { //Check 1 if false go to next object  in collection
        break;
      } else if (collection[i].hasOwnProperty(arr1[j])) {
        console.log(source[arr1[j]], collection[i][arr1[j]])
        if (source[arr1[j]] !== collection[i][arr1[j]]) { //Check 2 if value is not equal break loop and goto next object in collection
          break;
        }
        continue; // if both check passes go for  next  property of source to check in object;
      }
      result.push(collection[i]); //if all values are present and checked in object push it in result array.
    }
  }
  return result;
}

console.log(whatIsInAName(
  [
    { a: 1, b: 2 },
    { a: 1 },
    { a: 1, b: 2, c: 2 }
  ], {
    a: 1,
    b: 2
  }
));

我无法弄清楚逻辑中的问题。我尝试调试它甚至无法找到什么是逻辑上的问题。该程序是创建一个查看对象数组(第一个参数)的函数,并返回具有匹配属性的所有对象的数组价值对(第二个论点)请帮助我。

whatIsInAName([{ "a": 1, "b": 2 }, { "a": 1 }, { "a": 1, "b": 2, "c": 2 }], { "a": 1, "b": 2 }) 

应该返回

[{ "a": 1, "b": 2 }, { "a": 1, "b": 2, "c": 2 }].

whatIsInAName([{ "a": 1 }, { "a": 1 }, { "a": 1, "b": 2 }], { "a": 1 }) 

应该返回

[{ "a": 1 }, { "a": 1 }, { "a": 1, "b": 2 }].

5 个答案:

答案 0 :(得分:1)

使用这两个for循环你太复杂了,你可以使用Array内置方法做得更好。

您可以使用 How to call $scope.$apply() using "controller as" syntax .filter() 方法执行此操作:

function whatIsInAName(collection, source) {

    var result = [];
    var arr1 = Object.keys(source);
    console.log(arr1);

    result = collection.filter(function(obj){
          return !arr1.some(function(k){
              return !obj[k] || obj[k] !== source[k];
          });
    });
    return result;
    }

    console.log(whatIsInAName([{ a: 1, b: 2 }, { a: 1 }, { a: 1, b: 2, c: 2 }], { a: 1, b: 2 }));

答案 1 :(得分:0)

我认为你过于复杂化了。一个简单的.filter()就行了。在.filter()内,您可以使用方便的内置功能检查source中每个键的每个值是否与collection中的相应键匹配.every()方法。

&#13;
&#13;
function whatIsInAName(collection, source) {
  var sourceKeys = Object.keys(source);
  return collection.filter(function (coll) {
    // if you want to return only exact matches, just add the test to make sure same # of keys, and all keys match w/ values.
    // (Object.keys(coll).length === sourceKeys.length) && sourceKeys.every(...)
    return sourceKeys.every(function (key) {
      return coll[key] === source[key];
    });
  });
}

console.log(whatIsInAName(
  [
    { a: 1, b: 2 },
    { a: 1 },
    { a: 1, b: 2, c: 2 }
  ], {
    a: 1,
    b: 2
  }
));
&#13;
&#13;
&#13;

或者,使用ES6语法:

&#13;
&#13;
function whatIsInAName(collection, source) {
  return collection.filter(coll => Object.keys(source).every(key => coll[key] === source[key]));
}

console.log(whatIsInAName(
  [
    { a: 1, b: 2 },
    { a: 1 },
    { a: 1, b: 2, c: 2 }
  ], {
    a: 1,
    b: 2
  }
));
&#13;
&#13;
&#13;

答案 2 :(得分:0)

您的代码出现问题:

您目前正在做的是,如果所有if语句都通过,并且循环不会在任何地方中断,则再次在arr1的最后一项中继续。因此,它会检查下一次迭代,找不到它,然后进入集合循环中的下一次迭代。在执行此操作时,它不会推送任何项目。

<强>解决方案:

在你的代码中:你应该像这样继续使用。

if(j !==(arr1.length - 1)) 
  continue; 

这使您的代码有机会将项目推送到结果数组。

答案 3 :(得分:0)

尝试此功能

function whatIsInAName(arr, sources){
  return arr.filter((item) => {
    for(source in sources){
        if(!item[source] || item[source] !== sources[source]){
            return false;
        }
    }
    return true;
  })    
}

答案 4 :(得分:0)

你的问题是你正在继续而不是退出循环。我在这里更新了你的代码:

function whatIsInAName(collection, source) {
    var result = [];
    var arr1 = Object.keys(source);
    console.log(arr1);

    for (var i = 0; i < collection.length; i++) {
        for (var j = 0; j < arr1.length; j++) {
            if (!collection[i].hasOwnProperty(arr1[j])) { //Check 1 if false go to next object  in collection
                break;
            } else if (collection[i].hasOwnProperty(arr1[j])) {
                console.log(source[arr1[j]], collection[i][arr1[j]])
                if (source[arr1[j]] !== collection[i][arr1[j]]) { //Check 2 if value is not equal break loop and goto next object in collection
                  break;
                }else if(j < arr1.length - 1){
                    continue; // if both check passes go for  next  property of source to check in object;
                }

            }
            result.push(collection[i]); 
        }
    }
    return result;
}

console.log(whatIsInAName(
  [
    { a: 1, b: 2 },
    { a: 1 },
    { a: 1, b: 2, c: 2 }
  ], 
  {
    a: 1,
    b: 2
  }
)); // result is [Object {...}, Object {...}] which objects are {a: 1, b: 2}, {a: 1, b: 2, c: 2}