如何对一个比较器数组 ['<', '<=', '>', '>='] 进行比较?

3

更新

这里的思路是过滤掉数字,比如小于10或(小于等于10)或大于10或(大于等于10)的数字。

当用户输入像“显示所有小于或等于10的数字”这样的值时(输入将为<=10),我们的想法是使用比较过滤数组中的数字,当匹配特定数字时。

备注:v应该像这样<5或<10或<=3或<=2或>5或>=6等等...

nums.filter(num => {
    return comparisions.map(operation => {
        if (v.startsWith('>'))
        return num > parseInt(v.replace('>', '').trim());

        if (v.startsWith('>='))
        return num >= parseInt(v.replace('>=', '').trim());

        if (v.startsWith('<='))
        return num <= parseInt(v.replace('<=', '').trim());

        if (v.startsWith('<'))
        return num < parseInt(v.replace('<', '').trim());
    })
})

如何将上述重复内容整合为以下函数?



const comparisions = ['<', '<=', '>', '>=']

const nums = [3, 2, 1, 5, 6, 10]
// here I've shown only few a numbers for simplicity. In real it is a big array of nos.

nums.filter(num => {
    return comparisions.map(operation => {
        if (v.startsWith(operation))
        return num operation parseInt(v.replace(operation, '').trim());
    })
})

//example v = '<=10'

更新 请不要使用 eval() 函数。我不喜欢使用 eval 函数。


创建一个对象映射到返回基于比较的 true 或 false 的箭头函数?你也可以使用 eval,或者两者的组合。 - user120242
我对你的示例代码感到困惑。顶部的尝试似乎不能像下面的代码那样使用两个数组。输入是什么?为什么有6个数字需要4个运算符?我期望有5个运算符。 - user12407908
v 应该是什么? - user120242
这是代码。它很简单。想象一下这些形式的可能性:<5或<10或<=3或<=2或>5或>=6。它可以是任何以比较符号开头的数字。 - reacg garav
为什么不用 switch - Menai Ala Eddine - Aladdin
显示剩余6条评论
3个回答

3

构建一个操作到比较函数的对象映射,用于过滤。

假设v始终匹配“[匹配到比较函数的键][数字]”

const comparisions = {
  '<':  (x, y) => x < y,
  '<=': (x, y) => x <= y,
  '>':  (x, y) => x > y,
  '>=': (x, y) => x >= y
}
// you could also build functions that evaluate using eval or Function constructor based on the key(< or <= etc) provided

const nums = [3, 2, 1, 5, 6, 10]

v = "<=3"

console.log(
  nums.filter(num => {
    const [, op, n] = v.match(/^(.*?)(\d+)$/)
    return comparisions[op](num, n)
  })
)


我原本计划这样做。只是想知道是否有其他替代方案,不包括 eval()。这就是我发帖提问的原因。谢谢您的时间。 - reacg garav
你可以试着坚持下去,希望有人能想出什么办法。但是,根据定义,这是不可能的,正如我在其他答案的评论中所解释的那样。你最好澄清一下实际的完整用例。 - user120242
我不知道它是否能够代表你想要的,但是模板标签可能是另一个选项,但是再次强调,我不知道你的完整用例,所以我不知道那是否真的有帮助。通常类似于<= 10或函数已经足够简洁了。 - user120242

0
你可以像这样使用 eval:
let cmp = (input,op)=>(`${op}${input}`);
console.log(eval(`${1}${cmp(3,'<')}`)); // is 1 < 3 ?


你能否提供一个替代方案? - reacg garav
有一些问题我不能透露。出于安全考虑,这是不被推荐的。这就是原因。不要感到难过。 - reacg garav
如果您需要对任意语句或逻辑进行动态评估,那么您将无法避免使用 eval。如果您需要对其进行限制,则需要使用逻辑使其更加严格。这是根据定义不可避免的。 - user120242
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/eval#Never_use_eval! 告诉我哪一个是这里。 - Vahid Alimohamadi
1
这种情况不会发生,因为学生所做的事情的背景是受限制的。我不能要求他做任何我告诉他的事情,因为他自己的成长经历会告诉他不要这样做。在这种情况下,eval可以给出的域非常有限,因此这不是一个问题。因此,cybercoder提到了“安全问题是什么”。 - user120242
显示剩余10条评论

0

您可以使用类似 jexl 的包来评估表达式,但这可能是一种“大材小用”的解决方案。

但是,例如使用 jexl,您只需要执行以下操作:

nums.filter(num => jexl.evalSync(`${num}${v}`))

我觉得你没有理解。请再仔细阅读一遍简介。 - reacg garav
如果你说的是“请不要使用eval(),我不喜欢它”,这句话是我在写答案时添加的。 - samdouble

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接