【问题标题】:Search from multiple data source ( json)从多个数据源(json)中搜索
【发布时间】:2018-12-20 17:22:03
【问题描述】:

我正在从多个数据源中搜索一个字符串

下面是sn-p。用例:

  1. 搜索词:sample hybrid

  2. 预期行为:`它应该比较每个数据源中的每个单词,并在“searchResult['first']”和“searchResult['second']”中返回相应的对象。 即“样本”应在 2 个数据源中搜索并返回各自的对象,同样应该用于“混合”一词。

我做错了,得到一个空对象。

var dataSource1 = [{
  "_id": "5968dd23fc13ae04d9000001",
  "product_name": "sildenafil citrate",
  "supplier": "Wisozk Inc",
  "quantity": 261,
  "unit_cost": "$10.47"
}, {
  "_id": "5968dd23fc13ae04d9000002",
  "product_name": "Mountain Juniperus ashei",
  "supplier": "Keebler-Hilpert",
  "quantity": 292,
  "unit_cost": "$8.74"
}, {
  "_id": "5968dd23fc13ae04d9000003",

  "product_name": "Sample HBr",
  "supplier": "Schmitt-Weissnat",
  "quantity": 211,
  "unit_cost": "$20.53"
}];

var dataSource2 = [{
  "_id": "5968dd23fc13ae04d90000021",
  "product_name": "Hybrid product",
  "supplier": "Wisozk Inc",
  "quantity": 261,
  "unit_cost": "$10.47"
}, {
  "_id": "5968dd23fc13ae04d90000022",
 
  "product_name": "Mountain Sample Juniperus ashei",
  "supplier": "Keebler-Hilpert",
  "quantity": 292,
  "unit_cost": "$8.74"
}, {
  "_id": "5968dd23fc13ae04d90000033",
  
  "product_name": "Dextromathorphan HBr",
  "supplier": "Schmitt-Weissnat",
  "quantity": 211,
  "unit_cost": "$20.53"
}];

const searchCriteria = 'sample hybrid';
const searchResult = [];
function compareEachWord(str, searchCriteria) {
  var word = searchCriteria.split(" ");
  for(i=0; i<=word.length; i++) {
    return str.indexOf(word[i]) !== -1;
  }
}


function filterFromDS1() {
  const result =  _.filter(dataSource1, (item) => {
      return compareEachWord(_.toLower(item.product_name), searchCriteria);
  });
  return result;
}


function filterFromDS2() {
  const result =  _.filter(dataSource2, (item) => {
      return compareEachWord(_.toLower(item.product_name), searchCriteria);
  });
  return result;
}

searchResult['first'] = filterFromDS1();
searchResult['second'] = filterFromDS2();

console.log(searchResult);
&lt;script src="https://cdn.jsdelivr.net/npm/lodash@4.17.4/lodash.min.js"&gt;&lt;/script&gt;

【问题讨论】:

    标签: javascript ecmascript-6 lodash


    【解决方案1】:

    将单词转换为正则表达式(使用 i 标志 - 忽略大小写)并使用 RegExp.test() 查找单词是否包含在 product_name 中:

    // takes a criteria, converts to regex, and returns a filter function
    const filterByCriteria = (searchCriteria) => {
      const searchRegex = new RegExp(_.words(searchCriteria).join('|'), 'i');
      
      // the filtering functions expects a data souce and filters it
      return (ds) => ds.filter(o => searchRegex.test(o.product_name));
    };
    
    /** Usage: **/
    
    var dataSource1 = [{"_id":"5968dd23fc13ae04d9000001","product_name":"sildenafil citrate","supplier":"Wisozk Inc","quantity":261,"unit_cost":"$10.47"},{"_id":"5968dd23fc13ae04d9000002","product_name":"Mountain Juniperus ashei","supplier":"Keebler-Hilpert","quantity":292,"unit_cost":"$8.74"},{"_id":"5968dd23fc13ae04d9000003","product_name":"Sample HBr","supplier":"Schmitt-Weissnat","quantity":211,"unit_cost":"$20.53"}];
    
    var dataSource2 = [{"_id":"5968dd23fc13ae04d90000021","product_name":"Hybrid product","supplier":"Wisozk Inc","quantity":261,"unit_cost":"$10.47"},{"_id":"5968dd23fc13ae04d90000022","product_name":"Mountain Sample Juniperus ashei","supplier":"Keebler-Hilpert","quantity":292,"unit_cost":"$8.74"},{"_id":"5968dd23fc13ae04d90000033","product_name":"Dextromathorphan HBr","supplier":"Schmitt-Weissnat","quantity":211,"unit_cost":"$20.53"}];
    
    const searchCriteria = 'sample hybrid';
    
    const filterDs = filterByCriteria(searchCriteria);
    
    const searchResult = {
      first: filterDs(dataSource1),
      second: filterDs(dataSource2),
    };
    
    console.log(searchResult);
    &lt;script src="https://cdn.jsdelivr.net/npm/lodash@4.17.4/lodash.min.js"&gt;&lt;/script&gt;

    您的代码中的问题是立即返回的compareEachWord() 函数。由于您希望函数仅在结果为true 时立即返回,如果不是则迭代到最后,您可以使用Array.some()

    var dataSource1 = [{"_id":"5968dd23fc13ae04d9000001","product_name":"sildenafil citrate","supplier":"Wisozk Inc","quantity":261,"unit_cost":"$10.47"},{"_id":"5968dd23fc13ae04d9000002","product_name":"Mountain Juniperus ashei","supplier":"Keebler-Hilpert","quantity":292,"unit_cost":"$8.74"},{"_id":"5968dd23fc13ae04d9000003","product_name":"Sample HBr","supplier":"Schmitt-Weissnat","quantity":211,"unit_cost":"$20.53"}];
    
    var dataSource2 = [{"_id":"5968dd23fc13ae04d90000021","product_name":"Hybrid product","supplier":"Wisozk Inc","quantity":261,"unit_cost":"$10.47"},{"_id":"5968dd23fc13ae04d90000022","product_name":"Mountain Sample Juniperus ashei","supplier":"Keebler-Hilpert","quantity":292,"unit_cost":"$8.74"},{"_id":"5968dd23fc13ae04d90000033","product_name":"Dextromathorphan HBr","supplier":"Schmitt-Weissnat","quantity":211,"unit_cost":"$20.53"}];
    
    const searchCriteria = 'sample hybrid';
    const searchResult = {};
    function compareEachWord(str, searchCriteria) {
      var word = searchCriteria.split(" ");
      
      return word.some(w => str.includes(w));
    }
    
    
    function filterFromDS1() {
      const result =  _.filter(dataSource1, (item) => {
          return compareEachWord(_.toLower(item.product_name), searchCriteria);
      });
      return result;
    }
    
    
    function filterFromDS2() {
      const result =  _.filter(dataSource2, (item) => {
          return compareEachWord(_.toLower(item.product_name), searchCriteria);
      });
      return result;
    }
    
    searchResult['first'] = filterFromDS1();
    searchResult['second'] = filterFromDS2();
    
    console.log(searchResult);
    &lt;script src="https://cdn.jsdelivr.net/npm/lodash@4.17.4/lodash.min.js"&gt;&lt;/script&gt;

    【讨论】:

      【解决方案2】:

      您的searchResult 是数组。尝试将其更改为对象。

      searchResult = {}; 
      

      你会得到一个正确的结果。

      【讨论】:

        【解决方案3】:

        问题出在 compareEachWord 中

          for(i=0; i<=word.length; i++) {
            return str.indexOf(word[i]) !== -1;
          }
        

        return 语句正在停止循环。您应该使用辅助变量来比较所有单词

         var hasWord = false;
         for(i=0; i<=word.length; i++) {
            hasWord = (hasWord || str.indexOf(word[i]) !== -1);
          }
         return hasWord;
        

        【讨论】:

          【解决方案4】:

          几个问题。第一个是parndepu 标识的内容,即searchResult 应该是一个对象/哈希。第二个是您的方法compareEachWord 将始终返回搜索条件中第一个单词的搜索结果,即使它是错误的。它永远不会有机会搜索其他条件。

          作为奖励,我将您的方法 filterFromDS 重构为更干燥。

          编辑:更多的微优化,尤其是当您似乎在使用 ES6 时

          const dataSource1 = [{
            "_id": "5968dd23fc13ae04d9000001",
            "product_name": "sildenafil citrate",
            "supplier": "Wisozk Inc",
            "quantity": 261,
            "unit_cost": "$10.47"
          }, {
            "_id": "5968dd23fc13ae04d9000002",
            "product_name": "Mountain Juniperus ashei",
            "supplier": "Keebler-Hilpert",
            "quantity": 292,
            "unit_cost": "$8.74"
          }, {
            "_id": "5968dd23fc13ae04d9000003",
          
            "product_name": "Sample HBr",
            "supplier": "Schmitt-Weissnat",
            "quantity": 211,
            "unit_cost": "$20.53"
          }];
          
          const dataSource2 = [{
            "_id": "5968dd23fc13ae04d90000021",
            "product_name": "Hybrid product",
            "supplier": "Wisozk Inc",
            "quantity": 261,
            "unit_cost": "$10.47"
          }, {
            "_id": "5968dd23fc13ae04d90000022",
           
            "product_name": "Mountain Sample Juniperus ashei",
            "supplier": "Keebler-Hilpert",
            "quantity": 292,
            "unit_cost": "$8.74"
          }, {
            "_id": "5968dd23fc13ae04d90000033",
            
            "product_name": "Dextromathorphan HBr",
            "supplier": "Schmitt-Weissnat",
            "quantity": 211,
            "unit_cost": "$20.53"
          }];
          
          const searchCriteria = 'sample hybrid';
          const searchResult = {};
          
          function compareEachWord(str, searchCriteria) {
            const words = searchCriteria.split(" ");
            let hit = false;
            words.forEach(word => {
                if (str.indexOf(word) !== -1) hit = true;
            });
            return hit;
          }
          
          function filterFromDS(source) {
            const result = _.filter(source, item => {
                return compareEachWord(_.toLower(item.product_name), searchCriteria);
            });
            return result;
          }
          
          searchResult['first'] = filterFromDS(dataSource1);
          searchResult['second'] = filterFromDS(dataSource2);
          
          console.log(searchResult);
          &lt;script src="https://cdn.jsdelivr.net/npm/lodash@4.17.4/lodash.min.js"&gt;&lt;/script&gt;

          【讨论】:

            【解决方案5】:
                const _ = require('lodash')
            
            var dataSource1 = [{
                "_id": "5968dd23fc13ae04d9000001",
                "product_name": "sildenafil citrate",
                "supplier": "Wisozk Inc",
                "quantity": 261,
                "unit_cost": "$10.47"
            }, {
                "_id": "5968dd23fc13ae04d9000002",
                "product_name": "Mountain Juniperus ashei",
                "supplier": "Keebler-Hilpert",
                "quantity": 292,
                "unit_cost": "$8.74"
            }, {
                "_id": "5968dd23fc13ae04d9000003",
            
                "product_name": "Sample HBr",
                "supplier": "Schmitt-Weissnat",
                "quantity": 211,
                "unit_cost": "$20.53"
            }];
            
            var dataSource2 = [{
                "_id": "5968dd23fc13ae04d90000021",
                "product_name": "Hybrid product",
                "supplier": "Wisozk Inc",
                "quantity": 261,
                "unit_cost": "$10.47"
            }, {
                "_id": "5968dd23fc13ae04d90000022",
            
                "product_name": "Mountain Sample Juniperus ashei",
                "supplier": "Keebler-Hilpert",
                "quantity": 292,
                "unit_cost": "$8.74"
            }, {
                "_id": "5968dd23fc13ae04d90000033",
            
                "product_name": "Dextromathorphan HBr",
                "supplier": "Schmitt-Weissnat",
                "quantity": 211,
                "unit_cost": "$20.53"
            }];
            
            const searchCriteria = 'sample hybrid';
            const searchResult = [];
            function compareEachWord(str, searchCriteria) {
                var sample = searchCriteria.split(" ")[0]
                var hybrid = searchCriteria.split(" ")[1]
                return (str.match(sample) || str.match(hybrid))
            }
            
            
            function filterFromDS1() {
                const result = _.filter(dataSource1, (item) => {
                    return compareEachWord(_.toLower(item.product_name), searchCriteria);
                });
                return result;
            }
            
            function filterFromDS2() {
                const result = _.filter(dataSource2, (item) => {
                    return compareEachWord(_.toLower(item.product_name), searchCriteria);
                });
                return result;
            }
            searchResult['first'] = filterFromDS1();
            searchResult['second'] = filterFromDS2();
            
            console.log(searchResult);
            

            【讨论】:

              【解决方案6】:

              在这种情况下,searchResult 应该是一个 obj,我认为如果你只是重用功能而不是为你搜索的每个对象创建一个函数会更好

              function findTerm(arr, terms) {
                terms = terms.split(' ');
              
                return arr.filter( i => {
                  const productTerms = i.product_name.toLowerCase().split(' ')
                  for (let i = 0; i < productTerms.length; i++) {
                    if (terms.includes(productTerms[i])) return true;
                  }
                });
              }
              const searchCriteria = 'sample hybrid';
              const searchResult = {};
              searchResult['first'] = findTerm(dataSource1, searchCriteria);
              searchResult['second'] = findTerm(dataSource2, searchCriteria);
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2012-07-11
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-03-20
                • 2014-02-15
                • 2021-06-15
                • 2017-01-15
                相关资源
                最近更新 更多