在javascript中遍历对象,寻找嵌套属性并返回找到的对象

时间:2017-04-26 23:13:14

标签: javascript oop

我想编写一个函数来检查对象atrribute数组中是否包含关键字。如果在该数组中找到关键字,则应该返回该对象。

我尝试了下面的代码,但它没有用。我希望有一个聪明的人可以告诉我在这段代码中我做错了什么:)

我的目标是功能:ImageObjects.DE.brumi返回var ImageObjects = function() { var DE = { brumi : { name:"Brummi-Werk", keywords: ["brumi","auto", "LKWs", "lkws","lkw-werkstatt","die Brummis"] }, medien : { name: "medien", keywords:["vier","nummer vier", "springer", "neue medien", "neue medien ag", "die neue medien ag"] }, mautmaxe : { name: "mau", keywords:["fünf","nummer fünf", "mautmaxe", "maut", "currywust", "currywurst stand"] } }; return { DE: DE } }(); function searchObj(obj, query) { var data =''; for (var property in obj) { if (obj.hasOwnProperty(property)) { if (typeof obj[property] === "object") { data = searchObj(obj[property], query); if(data !='') return data; } else { if (obj["keywords"].indexOf(query) >= 0) { return obj; } else { return null; } } } } return data; } var Projects = function() { function detectProjectByKeyword(project) { var foundObject = null; for (var x in ImageObjects.DE){ if ((searchObj(ImageObjects.DE[x], project))!=null){ foundObject = searchObj(ImageObjects.DE[x], project) } } return foundObject; } return { detectProjectByKeyword: detectProjectByKeyword } }();

或许有更简单的方法来实现目标?我非常感谢任何帮助,因为我已经被困在这里一个多星期了:(

{{1}}

3 个答案:

答案 0 :(得分:1)

如果结构永远不变,IE; ImageObjects.LANGUAGE.project.keywords,这就足够了:

function detectProjectByKeyword(keyword, obj, language) {
  for(var a in obj[language]) {
    if(obj[language].hasOwnProperty(a)) {
      if(obj[language][a].keywords.indexOf(keyword) >= 0) return obj[language][a]
    }
  }
}

console.log(detectProjectByKeyword('brumi', ImageObjects, 'DE'));
console.log(detectProjectByKeyword('lkws', ImageObjects, 'DE'));
console.log(detectProjectByKeyword('mautmaxe', ImageObjects, 'DE'));

这是一个示例:https://jsfiddle.net/jorgthuijls/o2a01p6h/

答案 1 :(得分:1)

我已经冒昧地稍微改变了您的数据结构,但如果我正确理解您正在尝试做的事情,那么我希望以下内容能够发挥作用:



var ImageObjects =  {
  DE: {
      brumi : {
        name:                   "Brummi-Werk",
        keywords:               [
                                "brumi","auto", "LKWs", "lkws","lkw-werkstatt","die Brummis"
                                ]
    },
      medien : {
        name:                   "medien",
        keywords:               [
                                "vier","nummer vier", "springer", "neue medien", "neue medien ag", "die neue medien ag", 
                                /* added to demonstrate retrieving projects using a keyword shared across projects */, "brumi" 
                                ]
    },
      mautmaxe : {
        name:                   "mau",
        keywords:               [
                                "fünf","nummer fünf", "mautmaxe", "maut", "currywust", "currywurst stand"
                                ]
      }
  }
};

// Returns an array containing all projects with the keyword
// If only one project has a keyword, a one-element array will be returned
function findAllProjectsByKeyword(keyword) {
  var results = [];
  for (var country in ImageObjects) {
    for (var project in ImageObjects[country]) {
      var projectKeywords = ImageObjects[country][project].keywords;
      if ( projectKeywords && projectKeywords.indexOf(keyword) != -1 ) {
        results.push(ImageObjects[country][project]);
      }
    }
  }
  return results;
}

// Returns a single project with keyword
// If multiple projects have a keyword, only one will be returned
// The one that is returned may vary even for the same data, because the order
// of for-in loop enumeration may vary across implementations/runs
function findProjectByKeyword(keyword) {
  for (var country in ImageObjects) {
    for (var project in ImageObjects[country]) {
      var projectKeywords = ImageObjects[country][project].keywords;
      if ( projectKeywords && projectKeywords.indexOf(keyword) != -1 ) {
        return ImageObjects[country][project];
      }
    }
  }
}

// Example where a keyword is shared by two projects
var brumiProjects = findAllProjectsByKeyword('brumi');
console.log(brumiProjects.length);    // <= 2
console.log(brumiProjects[0].name);   // <= Brummi-Werk
console.log(brumiProjects[1].name);   // <= medien

// Only one project is returned with findProjectByKeyword, even if multiple projects have that keyword
console.log(findProjectByKeyword('brumi').name);  // <= Brummi-Werk (could be medien), depending on how the object is enumerated 

// Example where only one project has a keyword
console.log(findAllProjectsByKeyword('vier')[0].name); // <= medien
console.log(findProjectByKeyword('vier').name);        // <= medien
&#13;
&#13;
&#13;

ImageObjects结构有三个级别,country(我假设),项目和项目信息(名称和关键字)。 findAllProjectsByKeyword循环前两个级别,以便搜索所有国家/地区的所有项目。对于每个项目,它在项目对象的keywords数组中搜索关键字(作为findAllProjectsByKeyword的参数传递);如果找到关键字,则Array.indexOf返回索引 - 否则返回-1。如果找到关键字,则找到的项目对象将被推送到结果数组中。给定单个关键字,findAllProjectsByKeyword将找到多个项目。 findProjectByKeyword使用相同的方法,但只返回为给定关键字找到的第一个项目。

您可能还需要考虑其他细微之处;例如,Array.indexOf区分大小写,因此如果您搜索关键字&#39; Brumi&#39;,您将无法获得任何结果。

答案 2 :(得分:0)

如何通过多个关键字查找对象并使用现代ECMA-Script 2015及更高版本的工具和精彩内容呢?

请参阅以下代码段中的注释,以获取有关理解整个解决方案的见解:

&#13;
&#13;
var ImageObjects = {
  DE: {
    brumi: {
      name: "Brummi-Werk",
      keywords: [
        "brumi", "auto", "LKWs", "lkws", "lkw-werkstatt", "die Brummis"
      ]
    },
    medien: {
      name: "medien",
      keywords: [
        "vier", "nummer vier", "springer", "neue medien", "neue medien ag", "die neue medien ag", "mautmaxe"
      ]
    },
    mautmaxe: {
      name: "mau",
      keywords: [
        "fünf", "nummer fünf", "mautmaxe", "maut", "currywust", "currywurst stand", "springer"
      ]
    }
  }
};

// #1 Second parameter is a rest parameter. Second and any other parameter
//    will be captured as an array called "keywords"
// 
// #2 Object.keys returns own given object's properties (you don't need to
//    filter them out with x.hasOwnProperty("blah"))
//
// #3 For each property of a given language object, filter those
//    that contain the whole given keywords. The "...keywords" will
//    call Array.prototype.includes as many times as keywords you've
//    provided, and the operation will be done like using && (AND) logical
//    operator: all keywords should be present or it will be false.
//
// #4 Finally, Array.prototype.map gets the whole found property and returns
//    the object held by that property!
var findByKeywords = (language, ...keywords) =>
  Object.keys(ImageObjects[language])
  .filter(property => ImageObjects[language][property].keywords.includes(...keywords))
  .map(property => ImageObjects[language][property]);
  
var result = findByKeywords("DE", "mautmaxe", "springer");

console.log(result);
&#13;
&#13;
&#13;

进一步阅读: