web-dev-qa-db-ja.com

lodashを使用してオブジェクトの最初のn個の要素を取得する方法は?

Lodashを使用してobject(配列ではない)から最初のn個のキーと値のペアを取得したい。私は アンダースコアのこの答え を見つけました、これはusefirst(lodashには存在しない)を使用するか、またはtake(配列でのみ機能します)。

オブジェクトから「a:7」と「b:8」のペアを取得しようとするサンプルノードセッション:

> var ld=require("lodash")
undefined
> var o={a:7, b:8, c:9}
undefined
> ld.keys(o)
[ 'a', 'b', 'c' ]
> ld.take(o, 2)
[]
> ld.first(o, 2)
undefined
> 

確かに、lodashでこれを行う簡単な方法がいくつかあるに違いありませんが、私の人生では何も見つけることができません。多分私はネイティブのjsに頼らなければなりませんか?

8
vt5491

カスタムコードを記述しないと、オブジェクトの最初のN個の要素を取得できません。これは オブジェクト内の要素の順序付けなし があるためです。そのため、ライブラリ関数があったとしても、期待した要素が提供されるとは限りません。次のようなオブジェクトがあるとします

var obj = {  b: 3, y: 2, a: 1 };

「最初の2」が何を指しているのか明確ではありません-abのどちらが欲しいですか?これはアルファベット順ですか?もしそうなら、それらはその順序であるかどうか?そうでない場合、byが最初に表示されるため、これらを使用しますか? ayの値が最も低いため、おそらくそれらが必要ですか?

重複しないこと以外に何が得られるかについての保証はないため、これらの組み合わせはすべて有効です。さらに、任意の順序でそれらを取得できますyおよびaは同等に有効な出力ですどちらかを好むかもしれませんが、一般的には正しくありません。

これを回避する方法はいくつかありますが、非注文に対処する必要があることを受け入れる必要があります。

純粋なJavaScriptソリューション。

function firstN(obj, n) {
  return Object.keys(obj) //get the keys out
    .sort() //this will ensure consistent ordering of what you will get back. If you want something in non-aphabetical order, you will need to supply a custom sorting function
    .slice(0, n) //get the first N
    .reduce(function(memo, current) { //generate a new object out of them
      memo[current] = obj[current]
      return memo;
    }, {})
}
var obj = { b: 2, y: 25, a: 1 }

console.log( firstN(obj, 2) );

これは Object.keysArray.prototype.sort 、および Array.prototype.reduce を使用しています

Lodashでも同じことができますが、これよりもはるかに簡潔ではありません。同様の機能を呼び出す必要があります。たとえば、次のように実行できます。

function firstN(obj, n) {
  return _.chain(obj)
    .keys()
    .sort()
    .take(n)
    .reduce(function(memo, current) {
      memo[current] = obj[current];
      return memo;
    }, {})
    .value();
}

var obj = { b: 2, y: 25, a: 1 }
      
console.log( firstN(obj, 2) );
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>

ご覧のとおり、以前とほとんど同じです。構文にはバリエーションがあり、exactはこのタスクの実行方法を意味しますが、主要なポイントはまだそこにあるはずです-並べ替える必要があります一貫性とそして任意の数のアイテムを取得できます。

6
VLAZ

あなたがfirstのloadashのドキュメントを見れば。引数として配列のみを受け取り、これはおそらく使用するAPIではありません。

参照: https://lodash.com/docs/3.10.1#first


これは、標準のJavascript AP​​Iを使用して解決できる1つの方法です。

ここでの問題は、Object.keys(...)[index] AP​​Iを使用して、その位置に基づいて要素のキーを取得できることです。

次に、nをループし、派生キーを使用して別のオブジェクトにプッシュするだけです。

var firstN = 2;
var o={a:7, b:8, c:9};
var result = {};

for (var index=0; index < firstN; index++) {
  var key = Object.keys(o)[index];
  result[key] = o[key];
}

console.log(result);
4
Samuel Toh

簡単な解決策はありません。以前の回答とコメントに触発され、保証されていないプロパティの順序に関するいくつかの記事を読んで、最初にキーをソートするソリューションを作成しました。

キーの並べ替え

これがソートされたキーで使用可能な1行のアプローチです(したがって、順序は保証されています)。

連鎖

__.chain(object).toPairs().sortBy(0).take(2).fromPairs().value()
_

連鎖なし

__.fromPairs(_.take(_.sortBy(_.toPairs(object), 0), 2)),
_

ソートの詳細

sortBy(0)は、コレクションをkeys(index _0_)でソートします。 元のオブジェクトは最初にtoPairs()によってペアの配列に変換されます(各pairは配列_[key, value]_)であり、次にこれらの最初の値でソートされますpairskeyにはインデックスがあります_0_ペア).


重要:以前の回答やコメントで述べたように、最新のESバージョンであっても、プロパティの順序は保証されません。 this updated SO answer を参照してください。したがって、キーをソートしています。

0
exmaxx