【问题标题】:Javascript search through objectJavascript通过对象搜索
【发布时间】:2018-02-18 18:21:16
【问题描述】:

不幸的是,我对 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 search in object values 对未嵌套的对象执行了类似的操作,但我无法让它工作,也不知道如何使其适应具有 anamnese_akutanamnese_allgemein.

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

【问题讨论】:

  • 你能解释一下你想做什么吗?请提供输入和预期输出
  • 我没有得到你真正想要的东西。你能把问题说清楚一点吗?

标签: javascript object search


【解决方案1】:

我认为这里还有另一种结构化数据的方法。您可以避免使用数组并使用referencing by object properties。优点是,您可以通过对象的属性散列访问值,而无需“搜索”迭代。

注意:为了便于阅读,我在示例中只使用了您数据的一部分。

示例 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?']);

优点:答案立即返回

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

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

【讨论】:

    【解决方案2】:

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

    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 对象时。

    【讨论】:

      【解决方案3】:

      你可以通过以下方式做到这一点

      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);

      【讨论】:

        【解决方案4】:
        const input = "whatever";
        
        for(const category in items){
         for(const question of items[category]){
           if(question.question === input){
             //do whatever
             //optionally: return; 
           }
         }
        }
        

        In action

        或者如果您更喜欢函数式方法:

        const input = "whatever";
        const result = Object.values(items).reduce(
           (res,category)=> res || category.find(obj => obj.question === input ), false
        );
        

        In action

        【讨论】:

          【解决方案5】:

          为了获取内部数组的类别和索引,您可以迭代给定对象的键,然后迭代内部数组以检查问题。如果给定的字符串等于问题属性,则返回实际的类别和索引。如果没有找到结果,则返回undefined

          function find(object, search) {
              var result;
          
              Object.keys(object).some(function (k) {
                  return object[k].some(function (o, i) {
                      if (o.question === search) {
                          result = { category: k, index: i };
                          return true;
                      }
                  });
              });
          
              return result;
          }
          
          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.' }] };
          
          console.log(find(items, 'Sind bei Ihnen Vorerkrankungen bekannt?'));
          .as-console-wrapper { max-height: 100% !important; top: 0; }

          【讨论】:

            猜你喜欢
            • 2021-10-31
            • 1970-01-01
            • 2021-05-26
            • 2021-12-16
            • 1970-01-01
            • 2012-09-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多