【问题标题】:Searching for matching property and value pairs in an array of objects在对象数组中搜索匹配的属性和值对
【发布时间】:2016-01-20 12:08:54
【问题描述】:

我正在尝试解决 freeCodeCamp 练习,但遇到了困难。练习的目标是:创建一个函数,查看对象数组(第一个参数)并返回一个包含所有具有匹配属性和值对的对象的数组(第二个参数)。如果要包含在返回的数组中,源对象的每个属性和值对都必须存在于集合中的对象中。

所以我所做的就是制作一个包含集合的密钥对的数组,以及另一个包含源密钥对的数组。我嵌套了for循环以查找匹配的键,如果找到了这些键,则比较属性。

但不知何故,我的代码没有返回任何匹配项。

var collection = [{
  first: "Romeo",
  last: "Montague"
}, {
  first: "Mercutio",
  last: null
}, {
  first: "Tybalt",
  last: "Capulet"
}];
var source = {
  last: "Capulet"
};

var collectionKeys = [];
for (var i = 0; i < collection.length; i++) {
  collectionKeys.push(Object.keys(collection[i]));
}
var sourceKeys = Object.keys(source);

//for every key pair
for (var t = 0; t < collectionKeys.length; t++) {
  //for every key in key pair
  for (var x = 0; x < collectionKeys[t].length; x++) {
    //for every key in search
    for (var y = 0; y < sourceKeys.length; y++) {
      //see if a key matches
      if (sourceKeys[y] == collectionKeys[t][x]) {
        //see if the value matches
        if (collection[collectionKeys[t][x]] == source[sourceKeys[y]]) {
          console.log(collection[t]);
        } else {
          console.log("value not found");
        }
      } else {
        console.log("key not found");
      }
    }
  }
}

谁能指出我做错了什么?

如果你想修改,我还创建了一个 JSfiddle

【问题讨论】:

  • 更好的变量名称会为您提供更好的服务,包括创建一些临时变量以更好地表达您正在使用的内容。例如,sourcePropertyValuesource[sourceKeys[y]] 更易于阅读。如果您了解过函数,那么这个算法至少可以分解为两个函数。例如,我想要一个函数来确定两个对象是否匹配。

标签: javascript


【解决方案1】:

当我偶然发现一些可以提供帮助的资源时,我也被困了一个小时。

我发现我可以使用内置的循环方法来大大简化我的代码,而不是嵌套 for 循环的混乱。

我在这里找到了我的解释:

https://github.com/Rafase282/My-FreeCodeCamp-Code/wiki/Bonfire-Where-art-thou

function where(collection, source) {
  var arr = [];
  var keys = Object.keys(source);
  // Filter array and remove the ones that do not have the keys from source.
  arr = collection.filter(function(obj) {
    //Use the Array method every() instead of a for loop to check for every key from source.
    return keys.every(function(key) {
      // Check if the object has the property and the same value.
      return obj.hasOwnProperty(key) && obj[key] === source[key];
    });
  });

  return arr;
}

【讨论】:

    【解决方案2】:

    在您的声明中更加明确 - 有助于更轻松地阅读代码:

    var sourceKeys = Object.keys(source),
        i = 0, 
        j = 0,
        collectionLength = collection.length,
        sourceKeysLength = sourceKeys.length;
    
    while (i < collectionLength) {
        j = 0;
        while (j < sourceKeysLength) {
            if (sourceKeys[j] in collection[i] && source[sourceKeys[j]] === collection[i][sourceKeys[j]]) {
                console.log('found one!');
            }
            j++;
        }
        i++;
    }
    

    https://jsfiddle.net/fullcrimp/1cyy8z64/

    【讨论】:

      【解决方案3】:

      这里有一些见解,理解清晰,循环较少。

      一些新的 javascript 函数,如 some、filter、map 也非常方便使代码更整洁。

      function whatIsInAName(collection, source) {
        // What's in a name?
        var arr = [];
        // Only change code below this line
        collection.some(function(obj){
            var sk = Object.keys(source); //keys of source object
            var sv = Object.values(source); //values of source object
            var temp = 0; 
            for(i=0;i<sk.length;i++){ // run until the number of source properties length is reached.
              if(obj.hasOwnProperty(sk[i]) && obj[sk[i]] === sv[i]){ // if it has the same properties and value as parent object from collection 
                temp++; //temp value is increased to track if it has matched all the properties in an object
              }
            }
            if(sk.length === temp){ //if the number of iteration has matched the temp value 
              arr.push(obj);
              temp = 0; // make temp zero so as to count for the another object from collection
            }
        })
        // Only change code above this line
        return arr;
      }
      

      【讨论】:

        【解决方案4】:

        var collection = [{
          first: "Romeo",
          last: "Montague"
        }, {
          first: "Mercutio",
          last: null
        }, {
          first: "Tybalt",
          last: "Capulet"
        }];
        var source = {
          last: "Capulet"
        };
        
        var collectionKeys = [];
        for (var i = 0; i < collection.length; i++) {
          collectionKeys.push(Object.keys(collection[i]));
        }
        var sourceKeys = Object.keys(source);
        
        //for every key pair
        for (var t = 0; t < collectionKeys.length; t++) {
          //for every key in key pair
          for (var x = 0; x < collectionKeys[t].length; x++) {
            //for every key in search
            for (var y = 0; y < sourceKeys.length; y++) {
              //see if a key matches
              if (sourceKeys[y] == collectionKeys[t][x]) {
                if (collection[t][collectionKeys[t][x]] == source[sourceKeys[y]]) {
                 alert(collection[t].first+ " "+collection[t].last);
                } else {
                  console.log("value not found");
                }
              } else {
                console.log("key not found");
              }
            }
          }
        }

        collection[collectionKeys[t][x]] 更改为collection[t][collectionKeys[t][x]]..collection[collectionKeys[t][x]] 在控制台中给出undefined

        【讨论】:

          【解决方案5】:

          这就是我遇到相同问题的原因。

          function whereAreYou(collection, source) {
            // What's in a name?
          
            // Only change code below this line
          
            var arr = [];
            var validObject;
          
          // check each object
            for  (var each_object in collection ){
              validObject = true;
              for (var key in source ){
                if ( collection[each_object].hasOwnProperty(key)){
                  if ( collection[each_object][key] != source[key]){ 
                 // if no valid key
                 validObject = false;
               } 
             } else {
              // if no valid value
               validObject = false;
             }
           }
            // otherwise, give it a green light
           if(validObject){
            arr.push(collection[each_object]);
            }   
          }
          return arr;
          
          }
          

          【讨论】:

            【解决方案6】:
            function whatIsInAName(collection, source) {
              const keyCount = Object.keys(source).length;
              return collection.filter((item) => {
                return Object.entries(item).reduce((acc, [key, value], _, arr) => {
                  if (keyCount > arr.length) {
                    acc = false;
                  } else if (keyCount === arr.length && !source[key]) {
                    acc = false;
                  } else if (source[key] && source[key] !== value) {
                    acc = false;
                  }
                  return acc;
                }, true)
              })
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2021-01-18
              • 2022-09-23
              • 2023-01-10
              • 2015-07-06
              • 2012-05-20
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多