如何检查对象是否符合某些规则?

时间:2017-11-14 09:33:27

标签: javascript node.js

我有一系列类似的对象。我需要一个通用模板来为这个数组编写过滤规则。 例如,我有一系列电影:

const movies = [{
    title: 'movie 1',
    type: 'tv',
    genres: ['comedy', 'romantic']
}, {
    title: 'movie 2',
    type: 'serial',
    genres: ['comedy', 'romantic']
}, {
    title: 'movie 3',
    type: 'tv',
    genres: ['romantic', 'horror']
}]

并且规则

// Is Comedy movie
const rule = {
    relation: 'AND',
    items: [{
        property: 'type',
        value: 'tv'
    }, {
        property: 'genres',
        value: 'comedy'
    }]
}

检查结果:

// An improvised example of checking an object by a rule
checkObjByRule(rule, movies[0]) // -> true
checkObjByRule(rule, movies[1]) // -> false
checkObjByRule(rule, movies[2]) // -> false

在实际工作中,对象Movie要复杂得多,具有许多嵌套属性。我正在尝试找到一个现成的解决方案,一个库,以便我可以创建复杂的规则并检查它们

2 个答案:

答案 0 :(得分:1)

您可以将对象用于关系,并将Array#every用于ANDArray#some用于OR关系。

var movies = [{ title: 'movie 1', type: 'tv', genres: ['comedy', 'romantic'] }, { title: 'movie 2', type: 'serial', genres: ['comedy', 'romantic'] }, { title: 'movie 3', type: 'tv', genres: ['romantic', 'horror'] }],
    rule = { relation: 'AND', items: [{ property: 'type', value: 'tv' }, { property: 'genres', value: 'comedy' }] },
    result = movies.filter(
        o => rule.items[{ AND: 'every', OR: 'some' }[rule.relation]](
            r => o[r.property].includes(r.value)
        )
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:0)

尝试这种方法



var movies = [{
  title: 'movie 1',
  type: 'tv',
  genres: ['comedy', 'romantic']
}, {
  title: 'movie 2',
  type: 'serial',
  genres: ['comedy', 'romantic']
}, {
  title: 'movie 3',
  type: 'tv',
  genres: ['romantic', 'horror']
}];
var rule = {
  relation: 'AND',
  items: [{
    property: 'type',
    value: 'tv'
  }, {
    property: 'genres',
    value: 'comedy'
  }]
}

function processRules(obj, rule) {
  return rule.items.reduce(function(a, b) {
    if (typeof a != "boolean") { 
      var compareVal = obj[a.property];
      //compare the values here
      a = Array.isArray( compareVal ) ? compareVal.includes( a.value ) : compareVal == a.value; 
    }
    compareVal = obj[b.property];
    b = Array.isArray( compareVal ) ? compareVal.includes( b.value ) : compareVal == b.value;
    //based on the relation use the logical operators
    return rule.relation == "AND" ? a && b : a || b;
  });
}
console.log( processRules( movies[0], rule ) );
console.log( processRules( movies[1], rule ) );
console.log( processRules( movies[2], rule ) );