web-dev-qa-db-ja.com

JSONオブジェクト内のJavaScript検索

アプリケーションにJSON文字列/オブジェクトがありました。

{"list": [
    {"name":"my Name","id":12,"type":"car owner"},
    {"name":"my Name2","id":13,"type":"car owner2"},
    {"name":"my Name4","id":14,"type":"car owner3"},
    {"name":"my Name4","id":15,"type":"car owner5"}
]}

アプリケーションにフィルターボックスがあり、そのボックスに名前を入力すると、オブジェクトをフィルター処理して結果を表示する必要があります。

たとえば、ユーザーが「名前」と入力して検索をヒットした場合、MySQL検索のように、JSONオブジェクトでフルネームを検索し、配列を返す必要があります...

私の質問は、文字列でjsonオブジェクトをフィルタリングし、配列を返すことです...

32
ramesh

配列をループして、一致を見つけることができます。

var results = [];
var searchField = "name";
var searchVal = "my Name";
for (var i=0 ; i < obj.list.length ; i++)
{
    if (obj.list[i][searchField] == searchVal) {
        results.Push(obj.list[i]);
    }
}
34
McGarnagle

あなたの質問であれば、あなたのために検索を行う組み込みのものがありますか?いいえ、ありません。基本的に、 String#indexOf または 正規表現 のいずれかを使用して配列をループし、文字列をテストします。

ループには、少なくとも3つの選択肢があります。

  1. 退屈な古いforループ。

  2. ES5対応環境(またはシムを使用)では、 Array#filter

  3. JQueryを使用しているため、 jQuery.map

退屈な古いforループの例:

function search(source, name) {
    var results = [];
    var index;
    var entry;

    name = name.toUpperCase();
    for (index = 0; index < source.length; ++index) {
        entry = source[index];
        if (entry && entry.name && entry.name.toUpperCase().indexOf(name) !== -1) {
            results.Push(entry);
        }
    }

    return results;
}

obj.listsourceとして、目的の名前フラグメントをnameとして呼び出します。

または、空のエントリまたは名前のないエントリがある可能性がある場合は、ifを次のように変更します。

        if (entry && entry.name && entry.name.toUpperCase().indexOf(name) !== -1) {

Array#filterの例:

function search(source, name) {
    var results;

    name = name.toUpperCase();
    results = source.filter(function(entry) {
        return entry.name.toUpperCase().indexOf(name) !== -1;
    });
    return results;
}

繰り返しますが、空のエントリがある可能性がある場合(たとえば、undefined、欠落とは対照的に、filterはスキップmissingエントリ)、内部リターンを次のように変更します:

        return entry && entry.name && entry.name.toUpperCase().indexOf(name) !== -1;

jQuery.mapの例(ここでは通常jQuery = $と仮定しています。$jQueryに変更する場合はnoConflict):

function search(source, name) {
    var results;

    name = name.toUpperCase();
    results = $.map(source, function(entry) {
        var match = entry.name.toUpperCase().indexOf(name) !== -1;
        return match ? entry : null;
    });
    return results;
}

(必要に応じて、entry && entry.name &&を追加します。)

35
T.J. Crowder

PaulGuojSQL を使用します。これは、javascriptを使用するデータベースのようなSQLです。例えば:

var db = new jSQL();
db.create('dbname', testListData).use('dbname');
var data = db.select('*').where(function(o) {
    return o.name == 'Jacking';
}).listAll();
1
JackingLiu

JSONで動作するように正規表現を適合させました。

最初に、JSONオブジェクトを文字列化します。次に、一致した部分文字列の開始と長さを保存する必要があります。例えば:

"matched".search("ch") // yields 3

JSON文字列の場合、これはまったく同じように機能します(コンマと中括弧を明示的に検索する場合を除き、正規表現を実行する前にJSONオブジェクトを事前に変換することをお勧めします(つまり、think:、{、})。

次に、JSONオブジェクトを再構築する必要があります。私が作成したアルゴリズムは、マッチインデックスから再帰的に逆方向に移動してJSON構文を検出することでこれを行います。たとえば、擬似コードは次のようになります。

find the next key preceding the match index, call this theKey
then find the number of all occurrences of this key preceding theKey, call this theNumber
using the number of occurrences of all keys with same name as theKey up to position of theKey, traverse the object until keys named theKey has been discovered theNumber times
return this object called parentChain

この情報を使用して、正規表現を使用してJSONオブジェクトをフィルター処理し、キー、値、および親オブジェクトチェーンを返すことができます。

私が作成したライブラリとコードは http://json.spiritway.co/ で見ることができます。

0
mikewhit

アプリケーションの複数の場所でこれを実行している場合、array.filter()によって呼び出されるカスタム検索関数を作成することは面倒であり、代替手段より保守性が低いため、クライアント側のJSONデータベースを使用することは理にかなっています。

ForerunnerDBをチェックしてください。ForerunnerDBは、非常に強力なクライアント側JSONデータベースシステムを提供し、探していることを正確に行うのに役立つ非常にシンプルなクエリ言語を備えています。

// Create a new instance of ForerunnerDB and then ask for a database
var fdb = new ForerunnerDB(),
    db = fdb.db('myTestDatabase'),
    coll;

// Create our new collection (like a MySQL table) and change the default
// primary key from "_id" to "id"
coll = db.collection('myCollection', {primaryKey: 'id'});

// Insert our records into the collection
coll.insert([
    {"name":"my Name","id":12,"type":"car owner"},
    {"name":"my Name2","id":13,"type":"car owner2"},
    {"name":"my Name4","id":14,"type":"car owner3"},
    {"name":"my Name4","id":15,"type":"car owner5"}
]);

// Search the collection for the string "my nam" as a case insensitive
// regular expression - this search will match all records because every
// name field has the text "my Nam" in it
var searchResultArray = coll.find({
    name: /my nam/i
});

console.log(searchResultArray);

/* Outputs
[
    {"name":"my Name","id":12,"type":"car owner"},
    {"name":"my Name2","id":13,"type":"car owner2"},
    {"name":"my Name4","id":14,"type":"car owner3"},
    {"name":"my Name4","id":15,"type":"car owner5"}
]
*/

免責事項:私はForerunnerDBの開発者です。

0
Rob Evans