JavaScriptでオブジェクトの配列の値を見つける方法は?


90

オブジェクトの配列があります:

Object = {
   1 : { name : bob , dinner : pizza },
   2 : { name : john , dinner : sushi },
   3 : { name : larry, dinner : hummus }
}

キーが「夕食」である場所のオブジェクト/配列を検索して、それが「寿司」と一致するかどうかを確認できるようにしたいと思います。

私はjQueryに$ .inArrayがあることを知っていますが、オブジェクトの配列では機能しないようです。または多分私は間違っています。indexOfも1つの配列レベルでしか機能しないようです。

このための関数や既存のコードはありませんか?


これは以前に尋ねられました。独自の関数を記述するか、他のライブラリを使用する必要があります。
Felix Kling

1
ObjectJavaScriptで予約されてObjectいるのはオブジェクトオブジェクト、つまりすべてのオブジェクトの母であることに注意してください。
アダムス

1
質問と受け入れられた回答は、多次元配列に関連しているのではなく、アイテムのプロパティ値による1次元配列フィルタリングに関連しています。=>「多次元配列の値を見つける」という私の問題は解決されませんでした。
Martin Schneider

回答:


211

次のような配列がある場合

var people = [
  { "name": "bob", "dinner": "pizza" },
  { "name": "john", "dinner": "sushi" },
  { "name": "larry", "dinner": "hummus" }
];

filterArrayオブジェクトのメソッドを使用できます。

people.filter(function (person) { return person.dinner == "sushi" });
  // => [{ "name": "john", "dinner": "sushi" }]

新しいJavaScript実装では、関数式を使用できます。

people.filter(p => p.dinner == "sushi")
  // => [{ "name": "john", "dinner": "sushi" }]

"dinner": "sushi"使用している人を検索できますmap

people.map(function (person) {
  if (person.dinner == "sushi") {
    return person
  } else {
    return null
  }
}); // => [null, { "name": "john", "dinner": "sushi" }, null]

または reduce

people.reduce(function (sushiPeople, person) {
  if (person.dinner == "sushi") {
    return sushiPeople.concat(person);
  } else {
    return sushiPeople
  }
}, []); // => [{ "name": "john", "dinner": "sushi" }]

これを任意のキーと値に一般化できると確信しています!


7
これらのソリューションはECMAScript 5の一部であり、IE8ではサポートされていないことに注意してください。kangax.github.com/es5-compat-table 私が@adamseの答えを好むのと同じくらい、alexはより「古い古いブラウザ」に優しいです。ただし、パフォーマンスについてはわかりません。
EasyCo

@SalmanA-質問も解決策もjQueryを参照していません。JavaScriptのフィルタ()が使用され、jQueryのではない固有の$ .filter() - tutorialspoint.com/javascript/array_filter.htm
Tapirboy

EasyCoで述べたように、フィルター機能はIE8ではサポートされていません。ただし、これはArrayプロトタイプに簡単に追加できるため、スクリプトの最初に小さな関数があるブラウザーで使用できます。これはフィルターのドキュメントで概説されています。ECMA-262で指定された正確な関数を提供するので、文字通り同じです。
ダリン

1
jQueryのメソッドを使用する答えを追加しましgrep。あなたがしていることと同じ概念としてあなたの答えにロールインするのは理にかなっているかもしれませんが、jQueryに依存していて、ブラウザは使いやすいです。
Zach Lysobey 2013年

戻り変数で参照エラーが発生し続ける理由はありますか?「x」を返す上位2つの回答を試しましたが、それが未定義であると繰り返し表示されます...
Evan Lalo

18

jQueryには、@ adamseのAnswerのjQuery.grep ES5 filter関数と同様に機能する組み込みメソッドがあり、古いブラウザーで正常に機能するはずです。

adamseの例を使用:

var peoples = [
  { "name": "bob", "dinner": "pizza" },
  { "name": "john", "dinner": "sushi" },
  { "name": "larry", "dinner": "hummus" }
];

次のことができます

jQuery.grep(peoples, function (person) { return person.dinner == "sushi" });
  // => [{ "name": "john", "dinner": "sushi" }]

10
var getKeyByDinner = function(obj, dinner) {
    var returnKey = -1;

    $.each(obj, function(key, info) {
        if (info.dinner == dinner) {
           returnKey = key;
           return false; 
        };   
    });

    return returnKey;       

}

jsFiddle

-1有効なキーではない限り。


ほぼこれに賛成票を投じたが、記事には説明がなかった。
mickmackusa

10

この検索を頻繁に行う場合は、オブジェクトの形式を変更して、実際に夕食が重要になるようにすることを検討してください。これは、データベーステーブルにクラスター化された主キーを割り当てるようなものです。したがって、たとえば:

Obj = { 'pizza' : { 'name' : 'bob' }, 'sushi' : { 'name' : 'john' } }

これで、次のように簡単にアクセスできます。 Object['sushi']['name']

または、オブジェクトが本当にシンプルな場合(オブジェクトの 'name'のみ)、次のように変更できます。

Obj = { 'pizza' : 'bob', 'sushi' : 'john' }

その後、次のようにアクセスしますObject['sushi']

このようにデータオブジェクトを再構成することは必ずしも常に可能であるとは限りませんが、有利な点もありますが、ポイントは、データオブジェクトが最適な方法で構成されているかどうかを検討することです。このようなキーを作成すると、より速く、よりクリーンなコードを作成できます。


1
愛していますが、構文に問題が見つかりました:鉱山は次のようにしか機能しません:obj = {"pizza":{"name": "bob"}、 "sushi":{"name": "john"}}アラート( obj ['pizza'] ['name']); それでも。ありがとう!私が探していたものを見つけた!)
aleXela 2013

@alexelaありがとうalexela!私はあなたの鋭い観察で私の答えを更新しました!OPの投稿の例をコピーし、引用符を追加するのを怠っていましたが、そのとおりです-少なくとも値の前後に引用符がないと機能しません(それらは値であり、変数ではないと仮定します)。
ダリン

3

Alasqlライブラリを使用して配列内のオブジェクトを見つけることができます。

var data = [ { name : "bob" , dinner : "pizza" }, { name : "john" , dinner : "sushi" },
     { name : "larry", dinner : "hummus" } ];

var res = alasql('SELECT * FROM ? WHERE dinner="sushi"',[data]);

jsFiddleでこの例試してください。


3
これが実際に反対票を投じられるに値するかどうかはわかりません。コレクションに対するSQLのようなクエリは、要件が単一のフィルターや呼び出しの削減よりも複雑になると、推論と記述がはるかに容易になります。Alasqlはかなり印象的なライブラリですが、確かに上記の例では少しやりすぎです。
TomDotTom 2015

1
オブジェクト自体がSQLソースに由来する場合、この答えは純粋な天才です。
edwardsmarkf 2017年

1

単純なforループを使用できます。

for (prop in Obj){
    if (Obj[prop]['dinner'] === 'sushi'){

        // Do stuff with found object. E.g. put it into an array:
        arrFoo.push(Obj[prop]);
    }
}

次のフィドルの例では、含まdinner:sushiれているすべてのオブジェクトを配列に入れています。

https://jsfiddle.net/3asvkLn6/1/


1

ここにはすでに良い答えがたくさんありますので、もう1つではなく、lodashやunderscoreなどのライブラリを使用してください:)

obj = {
   1 : { name : 'bob' , dinner : 'pizza' },
   2 : { name : 'john' , dinner : 'sushi' },
   3 : { name : 'larry', dinner : 'hummus' }
}

_.where(obj, {dinner: 'pizza'})
>> [{"name":"bob","dinner":"pizza"}]

0

ネストされたサイトマップ構造で、特定のパスを作成する最初のリーフアイテムを検索する必要がありました。私は使用して次のコードを思い付いた.map() .filter().reduce。パスに一致する最後に見つかったアイテムを返します/c

var sitemap = {
  nodes: [
    {
      items: [{ path: "/a" }, { path: "/b" }]
    },
    {
      items: [{ path: "/c" }, { path: "/d" }]
    },
    {
      items: [{ path: "/c" }, { path: "/d" }]
    }
  ]
};

const item = sitemap.nodes
  .map(n => n.items.filter(i => i.path === "/c"))
  .reduce((last, now) => last.concat(now))
  .reduce((last, now) => now);

4n4904z07を編集


0

車輪を再発明しないようにします。すべてのデータ処理ニーズにオブジェクトスキャンを使用します。概念的には非常にシンプルですが、多くの優れた機能を備えています。特定の質問を解決する方法は次のとおりです

データ定義

const data = {
   1 : { name : 'bob' , dinner : 'pizza' },
   2 : { name : 'john' , dinner : 'sushi' },
   3 : { name : 'larry', dinner : 'hummus' }
};

論理

const objectScan = require('object-scan');

const scanner = (input) => {
  let obj = null;
  objectScan(['*.dinner'], {
    filterFn: (key, value, { parents }) => {
      if (value === 'sushi') {
        obj = parents[0];
      }
    },
    breakFn: () => obj !== null
  })(data);
  return obj;
};

const result = scanner(data);

出力

// => result
{
  "name": "john",
  "dinner": "sushi"
}

0

検索機能を使用して特定のオブジェクトを検索する場合は、次のようなことを試してください。

    function findArray(value){

        let countLayer = dataLayer.length;
        for(var x = 0 ; x < countLayer ; x++){

            if(dataLayer[x].user){
                let newArr = dataLayer[x].user;
                let data = newArr[value];
                return data;
            }

        }

        return null;

    }

    findArray("id");

これはオブジェクトの例です:

layerObj = {
    0: { gtm.start :1232542, event: "gtm.js"},
    1: { event: "gtm.dom", gtm.uniqueEventId: 52},
    2: { visitor id: "abcdef2345"},
    3: { user: { id: "29857239", verified: "Null", user_profile: "Personal", billing_subscription: "True", partners_user: "adobe"}
}

コードは「user」配列を反復して見つけ、あなたが探しているオブジェクトを検索します。

私の問題は、配列のインデックスがウィンドウの更新ごとに変更され、それが3番目または2番目の配列のいずれかにある場合でしたが、問題ではありません。

私の魅力のように働いた!

あなたの例では少し短いです:

function findArray(value){

    let countLayer = Object.length;
    for(var x = 0 ; x < countLayer ; x++){

        if(Object[x].dinner === value){
            return Object[x];
        }

    }

    return null;

}

findArray('sushi');
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.