Underscore where with or condition (underline, lodash or any other solution)

I implemented mixin to add an β€œor” condition using _.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();
   }
});

now i can use it like this and it works fine as sql query

_.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

but I want to find a better way to just call _.or ({a: 1}), right now I have to pass arr every time _.or (arr, {a: 1}), as the "or" chain gets the first object as a result previously performed functions.

Is there a way to get the whole array in a mixin function chain?

I want the same result returned below as my previous implementation. (like perfect sql query)

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

, , , , lodash - , . , , , . , . .

jsFiddle

+4
3

, - , . "" , .

- " ". 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. , or() end(), . end() , or() Userscore where() result. . or() , end() . whereOr() .

whereOr() chain() end() value().

jsFiddle

+1

, , , !

, , ( ). 2 , array propsObj , .

JsFiddle

+2

Try the following:

// makeOr is a constructor for a 'chainable' type with: `{or, value}`
var makeOr = () =>  {
  var fs = []
  var obj = {
    or: f => {
      fs.push(f)
      return obj
    },
    value: (arr) => _.chain(fs).map(f => _.where(arr, f)).union().flatten().value()
  }     
  return obj
}

// override underscore where 
// if f is our 'chainable' type we evaluate it, otherwise we default to underscore where
(function() {
  where = _.where
  _.mixin({
    where: (arr, f) => (!!f.value && !!f.or) ? f.value(arr) : where(arr, f)
  })
})();

var result = _.chain(arr)
  .where(makeOr().or({a: 1}).or({a:5}).or({a:11}))
  .where({a:5}).value()

Jsfiddle

PS. Check it out too: Hi, Underscore, you're doing it wrong!

+1
source

All Articles