0

次のjavascriptがあるとします

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'] = '//要素がHorrorである配列インデックス'?

または、myobj.movi​​es['-insert generatorhere-'] で映画のリストを取得する簡単な方法はありますか? アドバイスやサンプルをいただければ幸いです。

理想的な解決策がない場合は、どのライブラリを使用したサンプルでもかまいません。

4

4 に答える 4

1

シーヴェレンス、

特性を共有するオブジェクトのグループにアクセスする唯一の方法は、それらすべてを反復せずに、それらを挿入するときにそれらをすべてボックスに入れることです。もちろん、ボックスと言うときは、それらをまとめて保持するデータ構造のことを意味します。

とはいえ、考慮すべきいくつかの異なるシナリオを次に示します。

  1. 大量のアイテムのイテレータを作成し、必要なものを抽出するようにイテレータに指示します。実際には、すべてのアイテムを繰り返し処理していますが、必要なものをクエリするときに「怠惰」になることができます。これはおそらくあなたが望むものではありません。

  2. いくつかの共通のプロパティでそれらを分離しておきたいと本当に思っています。この場合、共通のプロパティ (ハッシュ テーブル) ごとに個別のバケットを作成します。

必要なものにすばやくアクセスできるため、オプション 2 をお勧めします。

Javascript でハッシュ テーブルを使用する方法を説明するリンクを次に示します: http://www.mojavelinux.com/articles/javascript_hashes.html

于 2012-07-12T16:34:04.973 に答える
0

線形パスを1回実行し、すべてのフィールドのインデックスを生成します。はい、それはゼロコストではありません。しかし、繰り返しになりますが、フリーランチのようなものはありません。

一般的に言えば、

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
...

古典的な時間と空間のトレードオフ。また、動作することを確認してください(JsFiddle)

于 2012-07-12T16:57:49.410 に答える
0

Well, I think a possible good way to do what you need is using jLinq.

Library: https://raw.github.com/hugoware/jlinq-beta/master/jlinq.js

This is my code but I also made you a jsfiddle:

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

Result:

enter image description here

Hope this helps :-)

于 2012-07-12T16:52:20.713 に答える
0

あなたが言及したように、ジャンルに基づいてタイトルのインデックスを保存することは、おそらくパフォーマンスの向上を保証できる最良の方法です (または、ソートされたストレージやバイナリ検索などを使用することもできますが、それはやり過ぎだと思います)。きれいな方法の 1 つは、名前付きの関数pushMovie(_name, _genre, ...)を Array プロトタイプに追加し、それを使用してムービーを作成することです。内部pushMovie(..)では、コードを記述してインデックスを作成することもできます..

于 2012-07-12T16:24:25.307 に答える