开发者问题收集

JavaScript 通过对象进行搜索

2017-09-10
845

不幸的是,我对 JS 中的对象仍然不太熟悉,而且只为攻读心理学博士学位而编程,所以我的编程技能并不出色。 我已经成功创建了一个不错的对象,它可以很好地捕获我的数据结构:

var items = {
  anamnese_akut: [{
    id: 1,
    question: 'Haben Sie die Beschwerden zum ersten Mal?',
    answer: 'Ja, also so etwas ist noch nie passiert.'
  }, {
    id: 2,
    question: 'Haben Sie in den letzten Wochen unbeabsichtigt Gewicht verloren?',
    answer: 'Nein, bestimmt nicht.'
  }],
  anamnese_allgemein: [{
    id: 3,
    question: 'Sind bei Ihnen Vorerkrankungen bekannt?',
    answer: 'Eigentlich nicht, nein.'
  }, {
    id: 4,
    question: 'Wurden Sie schon mal operiert?',
    answer: 'Ich hatte eine Blinddarmoperation als Kind, und in den letzten zwei Jahren dreimal eine Ausschabung nach Fehlgeburten.'
  }]
};    

我现在想搜索一个输入变量,它恰好包含这 4 个问题中的一个,但可以来自两个类别。我已经使用此处的代码对非嵌套对象进行了类似的操作: JS 在对象值中搜索 ,但我无法让它工作,也不知道如何将它调整为具有 anamnese_akutanamnese_allgemein 等类别的对象。

我该如何调整搜索?将输入与问题进行比较后,我希望有一个索引,以便我可以输出与找到的问题相对应的答案。

3个回答

我认为这里有另一种构造数据的方法。您可以避免使用数组,而使用 通过对象属性引用 。优点是,您无需通过迭代“搜索”即可访问值,而是通过对象的属性哈希值。

注意: 出于可读性目的,我在示例中仅使用了数据的简化子集。

示例 A - 基于索引号

var anamnese_akut = {
    q: {
  	1:'Haben Sie die Beschwerden zum ersten Mal?',
	2: 'Haben Sie in den letzten Wochen unbeabsichtigt Gewicht verloren?',
    },
  
    a: {
  	1:'Ja, also so etwas ist noch nie passiert.',
        2:'Nein, bestimmt nicht.'
    },
};

console.log(anamnese_akut.q['1']);
console.log(anamnese_akut.a['1']);

在此示例中,您将基于索引号(1、2、3...)获取数据,并通过该编号访问问题和答案。

优点: 不易出错,因为索引很短并且可以存储为数字。

缺点: 索引号必须在 q 和 a 的整体上下文中为人所知。

示例 B - 通过 Id 访问,但结构不同

var questions = {
    anamnese_akut: {
  	1:'Haben Sie die Beschwerden zum ersten Mal?',
        2:'Haben Sie in den letzten Wochen unbeabsichtigt Gewicht verloren?',
    },
};

var answers = {
    anamnese_akut: {
  	1: 'Ja, also so etwas ist noch nie passiert.',
        2: 'Nein, bestimmt nicht.',
    },
};

console.log(questions.anamnese_akut['1']);
console.log(answers.anamnese_akut['1']);

优点: 解耦问题和答案,访问时仅需要索引(如示例 A 中所示)

缺点: 在结构设计层面上需要做更多工作,因为这里有一点冗余(因为我们现在有两个带有 anamnese_akut 条目的对象)。

示例 C - 按问题访问

var anamnese_akut = {
    'Haben Sie die Beschwerden zum ersten Mal?' : 'Ja, also so etwas ist noch nie passiert.',
};

console.log(anamnese_akut['Haben Sie die Beschwerden zum ersten Mal?']);

优点: 立即返回答案

缺点: 问题字符串需要严格按照对象中给出的字符串,否则访问会失败并返回未定义。

我个人会选择示例 B,因为它允许我拆分问题和答案数据上下文(这可能变得很重要,具体取决于您的应用程序用例),并且仍然允许我通过一个给定的索引号进行访问。

Jankapunkt
2017-09-10

如果我正确理解您的意思:您的输入是问题文本,并且需要与这些对象之一匹配,那么这应该可以解决问题:

var input = 'Haben Sie die Beschwerden zum ersten Mal?' // For demo purposes.
var output = items.anamnese_akut.find(x => x.question === input) || items.anamnese_allgemein.find(x => x.question === input)

当然,这不是最优雅的解决方案,特别是如果您添加更多 anamnese 对象。

UncleDave
2017-09-10

您可以按照以下方式进行

var items = {
  anamnese_akut: [{
    id: 1,
    question: 'Haben Sie die Beschwerden zum ersten Mal?',
    answer: 'Ja, also so etwas ist noch nie passiert.'
  }, {
    id: 2,
    question: 'Haben Sie in den letzten Wochen unbeabsichtigt Gewicht verloren?',
    answer: 'Nein, bestimmt nicht.'
  }],
  anamnese_allgemein: [{
    id: 3,
    question: 'Sind bei Ihnen Vorerkrankungen bekannt?',
    answer: 'Eigentlich nicht, nein.'
  }, {
    id: 4,
    question: 'Wurden Sie schon mal operiert?',
    answer: 'Ich hatte eine Blinddarmoperation als Kind, und in den letzten zwei Jahren dreimal eine Ausschabung nach Fehlgeburten.'
  }]
};

let query = 'Wurden Sie schon mal operiert?';
let answer = Object.keys(items).reduce(function(a, b){
    let val = items[b].reduce(function(a, b){
        if(b.question == query){
            return b.answer;
        }
    }, "not available")
    if(val == "not available")
        return a;
    return val;
}, "not available");
console.log(answer);
marvel308
2017-09-10