过滤json类似于mysql“like”运算符

时间:2016-06-04 23:12:22

标签: javascript json filtering

我想过滤我的json,我尝试使用通配符 - “%”来模拟简单的mysql运算符“like”,但是有一个......某种“技巧”。

我们有一些项目:

var items =
[
    {id: 1,name: "Breaking Bad"},
    {id: 2,name : "Bates Motel"}
]

当我在PHP中使用PHP时,我使用'%'替换用户输入中的每个空格。因此,当用户输入“b ba”时,查询看起来像:

$this->db->query("SELECT * FROM items WHERE name LIKE '%b%ba% ");

用户获取项目:“打破坏”。我想用javascript和json模拟相同的行为。

我最接近的实现如下:

this.search = function() {
    var query = $.trim($('.player-search').val())
    query = query.toUpperCase()

    $.grep(that.items, function(v) {
        if(that.filter(v.name,query) === true) {
            $('.player-serial[data-id="'+v.id+'"]').fadeIn(200)
        } else {
            $('.player-serial[data-id="'+v.id+'"]').fadeOut(200)
        }
    })
}

this.filter = function(word,query) {
    var tmp = query.toUpperCase().split(" "),
        n = tmp.length,
        i = 0

    for(var k in tmp) {
        word.toUpperCase().indexOf(tmp[k]) >= 0 && ++i 
    }

    return (i == n) ? true : false
}

这种方式有一个可怕的错误,当用户键入“b ba”时,用户会收到“Breaking Bad”和“Bates Motel”,因为“Bates”这个词有“b”和“ba”。

在我再次尝试编写之前,我想问是否有更好/更聪明的方法来过滤json,因为我想要?可能是我试图再次发明轮子。

1 个答案:

答案 0 :(得分:2)

您可以使用$.grep()String.prototype.match()Array.prototype.every()String.prototype.slice()



var items = [{
  id: 1,
  name: "Breaking Bad"
}, {
  id: 2,
  name: "Bates Motel"
}];
var query = "b ba";
var res = $.grep(items, function(v) {
  // if space character included in query match first word to 
  // first word of `v.name`, last word to last word in `v.name`
  if (/\s/.test(query)) {
    var curr = v.name.match(/\w+/g).map(function(_q) {
      return _q.toLowerCase()
    });
    var q = query.match(/\w+/g);
    if (q.every(function(val, index) {
      return val === curr[index].slice(0, val.length)
    })) return true
  } else {
    if (q.toLowerCase() === v.name.toLowerCase().slice(0, q.length)) {
      return true
    }
  }
});

console.log(res[0])

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
&#13;
&#13;
&#13;