2015-12-30 4 views
5

lodash _.resultに引数を渡す方法はありますか?その場合、2番目の属性がメソッド名のときは?または、これを行う代わりの方法(好ましいlodash)がありますか?argadをlodashに渡す_.result

使用例は、このようなことができます:

var object = { 
    'cheese': 'crumpets', 
    'stuff': function(arg1) { 
    return arg1 ? 'nonsense' : 'balderdash'; 
    } 
}; 

_.result(object, 'cheese'); 
// => 'crumpets' 

_.result(object, 'stuff', true); 
// => 'nonsense' 

_.result(object, 'stuff'); 
// => 'balderdash' 

ありがとうございました。

+1

ドキュメントがショーに(私が正しく理解している場合)、このhttps://lodash.com/docs#resultを達成するためにどのような方法をいないようですので、私の推測では、これはサポートされていないことです。ここではhttps://github.com/lodash/lodash/issuesに特定のことを尋ねたり、追加の機能としてリクエストすることもできます。 – Xotic750

答えて

1

私はlodash _.result関数のソースコードを見ましたが、これはサポートされていません。これに独自の関数を実装し、_を使ってlodashを拡張することができます。 mixin

+0

非常に簡単なソリューションをありがとう! –

+0

この解決策はいくつかの点で '_.result'の完全な機能を提供していないことに注意してください。 – Xotic750

1

独自のミックスインを作成することができます。ここで私はlodashの内部動作の正確な機能を使用しているが、あなただけの暴露でそれを行うことができるかもしれまもなくリリースされるlodash 4.0.0

var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/; 
 
var reIsPlainProp = /^\w*$/; 
 
var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g; 
 
var reEscapeChar = /\\(\\)?/g; 
 

 
function isKey(value, object) { 
 
    if (typeof value == 'number') { 
 
    return true; 
 
    } 
 
    return !_.isArray(value) && 
 
    (reIsPlainProp.test(value) || !reIsDeepProp.test(value) || 
 
     (object != null && value in Object(object))); 
 
} 
 

 
function stringToPath(string) { 
 
    var result = []; 
 
    _.toString(string).replace(rePropName, function(match, number, quote, string) { 
 
    result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); 
 
    }); 
 
    return result; 
 
} 
 

 
function baseToPath(value) { 
 
    return _.isArray(value) ? value : stringToPath(value); 
 
} 
 

 
function parent(object, path) { 
 
    return path.length == 1 ? object : _.get(object, _.slice(path, 0, -1)); 
 
} 
 

 
function customResult(object, path, args, defaultValue) { 
 
    if (!isKey(path, object)) { 
 
    path = baseToPath(path); 
 
    var result = get(object, path); 
 
    object = parent(object, path); 
 
    } else { 
 
    result = object == null ? undefined : object[path]; 
 
    } 
 
    if (result === undefined) { 
 
    result = defaultValue; 
 
    } 
 
    return _.isFunction(result) ? result.apply(object, _.isArrayLike(args) ? args : []) : result; 
 
} 
 

 
_.mixin({ 
 
    'customResult': customResult 
 
}); 
 

 
var object = { 
 
    'cheese': 'crumpets', 
 
    'stuff': function(arg1) { 
 
    return arg1 ? 'nonsense' : 'balderdash'; 
 
    } 
 
}; 
 

 
var out = document.getElementById('out'); 
 
out.textContent = _.customResult(object, 'cheese') + '\n'; 
 
// => 'crumpets' 
 

 
out.textContent += _.customResult(object, 'stuff', [true]) + '\n'; 
 
// => 'nonsense' 
 

 
out.textContent += _.customResult(object, 'stuff') + '\n'; 
 
// => 'balderdash'
<script src="https://rawgit.com/lodash/lodash/master/lodash.js"></script> 
 
<pre id="out"></pre>

を使用した例でありますメソッド。私が数分余裕があれば、それが可能かどうか見ていきます。

公開されたメソッドのみを使用する際の問題は、正しいコンテキストで関数を実行する方法がないことです。

この方法では解決された値は、それがこの親オブジェクトの結合と その結果が返されると呼び出されます 関数の場合を除き、その_.getのようなものです。

+0

アイデアは明らかです、ありがとうございます。だから、それは深い '結果'のような、より一般的な課題を解決するようですね? –

+0

メソッド 'customResult'はメソッド' _.get'で、後で '_slice'ではなく' _.slice'でなければなりません。 –

+1

はい、この解決策は元の '_.result'のように動作し、' args'引数をメソッドに追加するだけです。 – Xotic750

1

はここで別のミックスインの実装です:

function myResult(obj, path, defaultValue) { 

    // Find any arguments beyond what's normally 
    // passed to result(). 
    var args = _.drop(arguments, 3); 

    // We need to know upfront whether or not this 
    // is a function we're dealing with. 
    var isFunc = _.isFunction(_.get(obj, path)); 

    // If this is a function, and there's arguments 
    // to apply, then use spread() and bindKey() to 
    // return the result of calling the method with arguments. 
    // Otherwise, it's just a plain call to result(). 
    if (isFunc && args.length) { 
     return _.spread(_.bindKey(obj, path))(args); 
    } else { 
     return _.result(obj, path, defaultValue); 
    } 
} 

_.mixin({ myResult: myResult }); 

アイデアは、我々は唯一のpath追加の引数が渡された関数である追加ケースを処理する必要があること。それ以外の場合は、基本的なresult()の実装に戻ります。

_.myResult(object, 'test'); 
// → undefined 

_.myResult(object, 'test', 15); 
// → 15 

_.myResult(object, 'cheese', 'wine'); 
// → "crumpets" 

_.myResult(object, 'stuff'); 
// → "balderdash" 

_.myResult(object, 'stuff', null, true); 
// → "nonsense"