オブジェクト保持キーのマッピング


129

mapunderscore.js の関数は、JavaScriptオブジェクトで呼び出された場合、オブジェクトの値からマッピングされた値の配列を返します。

_.map({one: 1, two: 2, three: 3}, function(num, key){ return num * 3; });
=> [3, 6, 9]

キーを保存する方法はありますか?つまり、私は返す関数が欲しい

{one: 3, two: 6, three: 9}

あなたは、私のように、代わりに新しいものを返すの実際のオブジェクトを変更する機能などの「mapValues」を探してここに来た場合は、外にこの単純な解決策を確認してください。stackoverflow.com/questions/30894044/...
マイケルTrouw

回答:


228

アンダースコア

アンダースコアは_.mapObject、値をマップしてキーを保持する機能を提供します。

_.mapObject({ one: 1, two: 2, three: 3 }, function (v) { return v * 3; });

// => { one: 3, two: 6, three: 9 }

DEMO


Lodash

Lodashは_.mapValues、値をマップし、キーを保持する機能を提供します。

_.mapValues({ one: 1, two: 2, three: 3 }, function (v) { return v * 3; });

// => { one: 3, two: 6, three: 9 }

DEMO


_.mapValues関数をアンダースコアに入れるための取り組みが行われています:関連する問題_mapValuesのプルリクエスト。これが
うまく

OBJECTをオブジェクトにしているかのように見えますか、それとも私は頭から離れていますか?
jsh 2015

@jshこの場合、_.map()[['one', 3], ['two', 6], ['three', 9]]配列の配列であるを返し、それを_.object()オブジェクトに戻しています。
Jezen Thomas

56

アンダースコアに似たユーティリティライブラリであるlodashで必要な関数を見つけることができました。

http://lodash.com/docs#mapValues

_.mapValues(object, [callback=identity], [thisArg])

オブジェクトと同じキーを持つオブジェクトと、コールバックを通じてオブジェクトのそれぞれの列挙可能なプロパティを実行することにより生成される値を持つオブジェクトを作成します。コールバックはthisArgにバインドされ、3つの引数で呼び出されます。(値、キー、オブジェクト)。


19

var mapped = _.reduce({ one: 1, two: 2, three: 3 }, function(obj, val, key) {
    obj[key] = val*3;
    return obj;
}, {});

console.log(mapped);
<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>


13

私はこれが古いことを知っていますが、今アンダースコアにはオブジェクトの新しいマップがあります:

_.mapObject(object, iteratee, [context]) 

もちろん、配列とオブジェクトの両方に対して柔軟なマップを作成できます

_.fmap = function(arrayOrObject, fn, context){
    if(this.isArray(arrayOrObject))
      return _.map(arrayOrObject, fn, context);
    else
      return _.mapObject(arrayOrObject, fn, context);
}

5
lodashユーザーへの注意:jdaltonは、この変更により、underscore.jsとの互換性壊すことにしました。lodashはサポートしませんmapObjectmapValues代わりにlodashのメソッドを見てください。
Mark Amery 2015

13

プレーンJS(ES6 / ES2015)のこのバージョンはどうですか?

let newObj = Object.assign(...Object.keys(obj).map(k => ({[k]: obj[k] * 3})));

jsbin

オブジェクトを再帰的にマップする(ネストされたオブジェクトをマップする)場合は、次のように実行できます。

const mapObjRecursive = (obj) => {
  Object.keys(obj).forEach(key => {
    if (typeof obj[key] === 'object') obj[key] = mapObjRecursive(obj[key]);
    else obj[key] = obj[key] * 3;
  });
  return obj;
};

jsbin

ES7 / ES2016以降Object.entries、次のObject.keysように使用できます。

let newObj = Object.assign(...Object.entries(obj).map([k, v] => ({[k]: v * 3})));

5

私はそれが長い時間であることを知っていますが、それでもフォールド(別名jsのreduce)を介した最も明白な解決策はありません。

function mapO(f, o) {
  return Object.keys(o).reduce((acc, key) => {
    acc[key] = f(o[key])
    return acc
  }, {})
}

私はLodashライブラリの使用で大丈夫ですが、プログラマーはこれらの種類のライブラリを使用しており、これがバニラJSでどのように実現できるかを知りません。だから、私はあなたの答えに感謝します!
2018年

3

_。地図はオブジェクトではなく配列を返します。

オブジェクトが必要な場合は、次のような別の関数を使用したほうがよいでしょうeach。あなたが本当にマップを使いたいなら、あなたはこのようなことをすることができます:

Object.keys(object).map(function(value, index) {
   object[value] *= 3;
})

しかし、それは混乱を招きmapます。結果として配列があり、それを使って何かを作成することを期待しているのを見たとき。


私は、underscore.jsでこれを試すのは自然ではないというドキュメントを読んでいるような気がしました。私の使用例はかなり自然だと思いますが、なぜそれをサポートしないのですか?
xuanji 2013

一つの理由は、おそらくその可能性がmap出力として配列を生成する入力を変更するために使用され、あなたが作曲ができ_.object及び_.map@GGとして。書いたが、それは現時点では好みの問題だ。
Alberto Zaccagni 2013

3

自分で実装するのに十分簡単な(オブジェクトの値に関数をマップするための)mapValues関数が必要だと思います。

mapValues = function(obj, f) {
  var k, result, v;
  result = {};
  for (k in obj) {
    v = obj[k];
    result[k] = f(v);
  }
  return result;
};


0

アンダースコアマップのバグの混合修正:P

_.mixin({ 
    mapobj : function( obj, iteratee, context ) {
        if (obj == null) return [];
        iteratee = _.iteratee(iteratee, context);
        var keys = obj.length !== +obj.length && _.keys(obj),
            length = (keys || obj).length,
            results = {},
            currentKey;
        for (var index = 0; index < length; index++) {
          currentKey = keys ? keys[index] : index;
          results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
        }
        if ( _.isObject( obj ) ) {
            return _.object( results ) ;
        } 
        return results;
    }
}); 

正しいキーを保持し、オブジェクトとして返す単純な回避策これは、この関数を使用してバグの多い_.map関数をオーバーライドすることができたゲストと同じように使用されます。

または単に私がミックスインとしてそれを使用したように

_.mapobj ( options , function( val, key, list ) 

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