2015-12-30 7 views
5

Gibt es eine Möglichkeit, Argumente an lodash _.result übergeben, für den Fall, wenn das zweite Attribut Methodenname ist? Oder gibt es eine alternative Methode (bevorzugt lodash), dies zu tun?Pass Argumets zu lodash _.result

Usage Beispiel könnte so aussehen:

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

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

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

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

Danke.

+1

Die Dokumente scheinen keine Möglichkeit zu zeigen, dieses https://lodash.com/docs#result zu erreichen (wenn ich das richtig verstehe), so meine Vermutung ist, dass dies nicht unterstützt wird. Sie könnten hier https://github.com/lodash/lodash/issues fragen, um sicher zu sein, oder es sogar als zusätzliches Feature anfordern. – Xotic750

Antwort

1

Ich schaute auf den Quellcode von lodash _.result Funktion und es gibt keine Unterstützung dafür. Sie können dafür eine eigene Funktion implementieren und lodash mit _ erweitern. mixin.

function myResult(object, path, defaultValue) { 
    result = object == null ? undefined : object[path]; 
    if (result === undefined) { 
     result = defaultValue; 
    } 
    return _.isFunction(result) 
     ? result.apply(object, Array.prototype.slice.call(arguments, 2)) 
     : result; 
} 

// add our function to lodash 
_.mixin({ myResult: myResult}) 


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

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

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

Danke für die ziemlich einfache Lösung! –

+0

Beachten Sie, dass diese Lösung nicht auf mehrere Arten die vollen Möglichkeiten von '_.result' bietet. – Xotic750

1

Sie könnten Ihr eigenes Mixin erstellen. Hier ist ein Beispiel, die bald mit 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>

ich verwendet habe, um die genaue Funktionen der internen Abläufe lodash freigegeben werden, aber sie können in der Lage sein, es zu tun mit nur ausgesetzt Methoden. Wenn ich ein paar Minuten Zeit habe, werde ich nachsehen, ob es möglich ist.

Das Problem mit nur exponierten Methoden ist, dass ich keine Möglichkeit sehe, die Funktion mit dem richtigen Kontext auszuführen.

Diese Methode ist wie _.get außer, dass, wenn der aufgelöste Wert ist eine Funktion mit der dieser Bindung seines übergeordneten Objekts aufgerufen wird und das Ergebnis zurückgegeben.

+0

Die Idee ist klar, danke. So scheint es, als ob es eine allgemeinere Aufgabe löst, wie tiefes "Ergebnis"? –

+0

In der Methode 'customResult' sollte die Methode' _.get' und später '_.slice' anstelle von' _slice' sein, denke ich. –

+1

Ja, diese Lösung funktioniert genau wie das Original '_.result', sie fügt der Methode nur das Argument' args' hinzu. – Xotic750

1

Hier ist eine andere mixin Implementierung:

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

Die Idee ist, dass wir müssen nur den zusätzlichen Fall behandeln, in denen path eine Funktion und zusätzliche Argumente übergeben wurden. Andernfalls kehren wir zu der grundlegenden Implementierung result() zurück.