Рекурсивная функция для форматирования вложенных массивов для сопоставления с массивами условий - PullRequest
3 голосов
/ 07 мая 2020

Попытка написать эту функцию eval, которая принимает случаи, перебирает их в цикле и должна проверять, соответствует ли она условию в массиве условий и возвращает истину или ложь. Я не уверен, как лучше всего отформатировать массив условий и выполнить на нем сопоставление. Условия вложены на n уровней в глубину, поэтому мы пытаемся получить рекурсивную функцию.

console.log(cases.forEach(c => eval(formattedCondition, c.item)))

const conditions = [
 "OR",
 ["AND",["==","maker","airbus"],["==","name","A320"]],
 ["AND",[ "==", "maker","boeing"]],
 ["OR",["==","name","B767"]]
]

const cases = [
 {
   "item": {
    'maker': 'airbus',
    'name':"A320",
   }
 // should return true for this case
 },
 {
   "item": {
    'maker': 'embraer',
    'name':"e175",
   }
 // should return false for this case
 },
 {
   "item": {
    'maker': 'boeing',
   }
 // should return true for this case
 },
 {
   "item": {
    'name':"B767",
   }
// should return true for this case
 },
 {
   "item": {
    'maker': 'boeing',
    'name':"B777",
   }
 // should return false for this case
 },
]

1 Ответ

3 голосов
/ 08 мая 2020

Вы можете воспользоваться подходом без eval и использовать данные для построения выражений с функцией проверки с равными и некоторыми квантователями для AND и OR.

const
    conditions = ["OR", ["AND", ["==", "maker", "airbus"], ["==", "name", "A320"]], ["AND", ["==", "maker", "boeing"]], ["OR", ["==", "name", "B767"]]],
    take = object => {
        const
            quantifiers = { AND: 'every', OR: 'some' },
            operators = { '==': (a, b) => a == b },
            evaluate = ([symbol, ...values]) => values.every(v => typeof v === 'string')
                ? operators[symbol](object[values[0]], values[1])
                : values[quantifiers[symbol]](evaluate);
        return evaluate;
    },
    cases = [
        { item: { maker: 'airbus', name: "A320" } },    // true
        { item: { maker: 'embraer', name: "e175" } },   // false
        { item: { maker: 'boeing' } },                  // true
        { item: { name: "B767" } },                     // true
        { item: { maker: 'boeing', name: "B777" } },    // true instead of false
    ],
    result = cases.map(({ item }) => take(item)(conditions));

console.log(result);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...