快速访问javascript数组中的分类元素?

时间:2012-07-12 16:15:10

标签: javascript

说我有以下javasccript

var myobj = {
   name: "Julia",
   birthdate: "xxxx",
   movies: [{title: "movie1", rating: 5, genre: "Horror"}, {title: "movie2", rating 3, genre: "Comedy"},{title: "movie3", rating 3, genre: "Comedy"}, {title: "movie4", rating 3, genre: "Comedy"}, {title: "movie5", rating 3, genre: "Horror"}]
}

我正在寻找检索所有“恐怖”电影(可能是喜剧)的最佳方式,而无需遍历数组中的所有内容。我知道我可以使用if条件创建一个for循环迭代电影数组,但这需要我查看每一部电影。如果有某种方法我可以做:

horrorMovies = [//array containing all horror movies without iterating through everything to iterate through all moves to look at their genre attribute]

或者在myobj中添加一些额外字段作为某种查找表是一种好习惯:

myobj.genreindexes = [];

并跟踪所有类型:genreindexes ['Horror'] ='//数组索引元素是恐怖'?

还是有一些简单的方法可以做:myobj.movi​​es [' - insert genrehere-']并获取电影列表?任何建议和样品将不胜感激。

如果没有理想的解决方案,使用任何库的样本也可以。

4 个答案:

答案 0 :(得分:1)

Seiverence,

访问共享特征而不迭代所有特征的一组对象的唯一方法是在插入它们时将它们全部放在一个框中。当然,当我说框时,我的意思是在数据结构中将它们保持在一起。

那就是说,这里有一些不同的场景需要考虑:

  1. 你为一大堆物品编写了一个迭代器,并告诉迭代器提取你想要的东西。实际上,您正在迭代所有项目,但它允许您在查询所需内容时“懒惰”。这可能不是你想要的。

  2. 你真的想让它们被一些共同财产分开。在这种情况下,您为每个公共属性(哈希表)创建单独的存储桶。

  3. 我建议选项2,因为它可以快速访问您想要的内容。

    这是一个解释如何在Javascript中使用哈希表的链接: http://www.mojavelinux.com/articles/javascript_hashes.html

答案 1 :(得分:0)

正如您所提到的,根据流派存储标题索引可能是保证性能提升的最佳方式(或者您可以选择排序存储和二进制搜索等,但我认为这将是一种过度杀伤力)。一种干净的方法是将一个名为pushMovie(_name, _genre, ...)的函数添加到Array原型中,并使用它来填充电影。在pushMovie(..)内,您可以编写代码来填充索引..

答案 2 :(得分:0)

嗯,我认为做一个可能的好方法就是使用jLinq。

图书馆: https://raw.github.com/hugoware/jlinq-beta/master/jlinq.js

这是我的代码,但我也让你成为了一个jsfiddle:

演示: http://jsfiddle.net/oscarj24/anMDt/

//Your json obj array
var myobj = {
   name: "Julia",
   birthdate: "xxxx",
   movies: [{title: "movie1", rating: 5, genre: "Horror"}, {title: "movie2", rating: 3, genre: "Comedy"},{title: "movie3", rating: 3, genre: "Comedy"}, {title: "movie4", rating: 3, genre: "Comedy"}, {title: "movie5", rating: 3, genre: "Horror"}]
}

//Just horror movies in object
var horrorMovies = jlinq.from(myobj.movies).starts('genre', 'Horror').select();

// See the console with your horror movies
console.log(horrorMovies);

<强>结果:

enter image description here

希望这会有所帮助: - )

答案 3 :(得分:0)

执行一次线性传递,并为所有字段生成索引。是的,它不是零成本;但话说回来,没有免费的午餐。

一般来说,

function index(array) {
    var fields = {}
    for (var i=0; i<array.length; i++) {
        var o = array[i]
        for (var f in o) {
            if ( ! o.hasOwnProperty(f)) {
               continue;
            } else if (fields[f] === undefined) {
                fields[f] = {};
                fields[f][o[f]] = [o];
            } else if (fields[f][o[f]] === undefined) {
                fields[f][o[f]] = [o];
            } else {
                fields[f][o[f]].push(o);
            }
        }
    }
    return fields;
}

这允许你写

var db = index(myobj.movies); // takes O(C), where C = number of rows x cols 
db["genre"]["Comedy"];         // returns an array w/ movies 2, 3, 4 - in O(1)
db["genre"]["Horror"];         // returns an array w/ movies 1, 5
...

经典的时空权衡。另外,see it working (JsFiddle)