web-dev-qa-db-ja.com

オブジェクト保存キーを介したマップ

Underscore.jsのmap関数は、javascriptオブジェクトで呼び出された場合、オブジェクトの値からマップされた値の配列を返します。

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

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

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

WithUnderscore

アンダースコアは、値をマッピングしてキーを保持するための関数 _.mapObject を提供します。

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

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

DEMO


WithLodash

Lodashには、値をマッピングしてキーを保持するための関数 _.mapValues が用意されています。

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

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

DEMO

210
GG.

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

http://lodash.com/docs#mapValues

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

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

56
xuanji
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>
19
kunalgolani

これは古いことは知っていますが、Underscoreにはオブジェクトの新しいマップがあります:

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

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

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

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

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

jsbin

オブジェクトを再帰的にマッピングする(ネストされたobjをマッピングする)場合は、次のようにします。

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})));
10
Rotareti

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

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

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

しかし、mapを見ると、結果として配列が得られ、それで何かを作成することが期待されます。

3

私はそれが長い時間であることを知っていますが、それでも折り畳みによる最も明白な解決策(別名jsでのreduce)がありません。完全を期すためにここに残しておきます:

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

mapValues 関数(オブジェクトの値に関数をマッピングするため)が必要だと思いますが、これは簡単に実装できます。

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

混合修正アンダースコアマップbug: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関数をオーバーライドできるiゲストと同じ方法で使用されます

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

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

Lodashでは_.mapValues(users, function(o) { return o.age; });を、アンダースコアでは_.mapObject({ one: 1, two: 2, three: 3 }, function (v) { return v * 3; });を使用できます。

こちらのクロスドキュメントをご覧ください: http://jonathanpchen.com/underdash-api/#mapvalues-object-iteratee-identity

0
luxon