javascript – 下划线或条件(下划线,lodash或任何其他解决方案)

我实现了一个mixin,用_.where添加“或”条件

var arr = [{a:1,b:4}, {a:5}, {a:6}, {a:11}];
_.mixin({
   or: function(obj,arr,condition){
     return _.chain(arr).where(condition).union(obj).value();
   }
});

现在我可以像这样使用它,它的工作方式有点像sql查询

_.chain(arr).where({a:1}).or(arr,{a:11,b:3}).or(arr,{a:2}).value();
//returns [{a:1,b:4}]

_.chain(arr).where({a:1}).or(arr,{a:11}).or(arr,{a:2}).value();
//returns [{a:1,b:4},{a:11}]

_.chain(arr).where({a:1}).or(arr,{a:11}).or(arr,{b:4}).value();
//returns [{"a":1,"b":4},{"a":11}] --no duplicates

但我想找到一个更好的方法来调用_.or({a:1}),现在我必须每次__or(arr,{a:1})传递arr,因为链接“或”得到第一个object作为先前执行的函数的结果.

有没有办法在链式mixin函数中获得整个数组?

我想在下面返回与上述实现相同的结果. (就像一个完美的SQL查询)

_.chain(arr).where({a:1}).or({a:11,b:3}).or({a:2}).value();//returns [{a:1,b:4}]

我的主要关注点是通过下划线,但实际上任何其他方式,如lodash甚至其他一些库或解决方案也会起作用.此外,我们不需要使用链接,我也尝试使用compose,但到目前为止还没有运气.我想要一个在最小线条上完美运行的解决方案.鼓励任何其他建议使其更好.

jsFiddle

解决方法:

我不认为扩展下划线是正确的方式,Underscore的链接不是为此而设计的.你可以“弯曲”它,但是以你想要的短缺为代价.

链条如何工作

Underscore的链接是一种“流操作”. chain()将传递的对象内部存储在闭包中,并返回Underscore接口,其中每个方法都绑定到该对象.应用过滤器函数时,将返回结果并将其内部存储在结果对象中.然后value()调用将返回内部引用.

定制解决方案

您可以使用所谓的流畅界面解决此问题:

// Fluent interface to filter an array with chained, alternative conditions.
// Usage: whereOr([...]).or({...}).or({...}).end()
//        whereOr([...], {...}).or({...}).end()
// Objects are _.where() conditions to subsequently apply to the array.
function whereOr(arr, condition) {
    var result = [],
        iface;

    iface =  {
        or: function(subcondition) {
            result = result.concat(_.where(arr, subcondition));
            return iface;
        },
        end: function() {
            return _.union(result);
        }
    };

    if (condition) {
        return iface.or(condition);
    }

    return iface;
}

然后你可以做

var arr = [{a:1,b:4}, {a:5}, {a:6}, {a:11}];
whereOr(arr).or({a:1}).or({a:11}).or({a:2}).end();

如果您愿意,可以将此功能混合到Underscore中,当然:

_.mixin({
    whereOr: whereOr
});

这个怎么运作

当调用whereOr()时,它会建立一个范围来保存对原始arr的引用.它返回一个提供fluent函数的对象,或者()和end()都可以访问初始数组. end()将返回结果,或者()将Userscore的where()应用于内部引用,并将结果添加到result.然后它再次返回接口对象.这种方式或()提供了另一种过滤的可能性,直到end()返回联合结果.在此示例中,whereOr()可选地接受第一个过滤条件作为第二个参数.

您可以将whereOr()与chain()和end()与value()进行比较.

jsFiddle

上一篇:基于序列javascript拆分数组


下一篇:javascript – 使用两个不同的数组创建一个分组数组