JS函数在大于或小于之间切换

时间:2019-06-18 12:39:04

标签: javascript

我有一个很长的函数,此刻我需要一个函数的副本,唯一的区别是它要求大于而不是小于。因此,唯一的区别是>或<。

是否有(非凌乱的)方式使这种功能只是一个功能而不是这里的两个功能?

function(value, modifier) {
 let result;
 if (value > modifier) result = 10;
 return result;
}

function(value, modifier) {
 let result;
 if (value < modifier) result = 10;
 return result;
}

所以基本上,我需要一个大于/小于符号的条件。

编辑:要清楚,在理想的世界中,我想这样做:

myFunction(10, 5, >)

编辑:添加我实际功能的一部分以使事情更清楚。我希望可能有一种真正简单的方法来执行此操作,但似乎并非如此,实际功能的一部分可能会有所帮助:

function getEdges(colour) {
    for (let x = 0; x < width; x++) {
        for (let y = height - 1; y >= 0; y--) {
            const data = getData(x,y);
            if (data[0] < colour) {
                edge.push(y);
                break;
            }
        }
    }
    return edge;
    }

还有另一个几乎相同的函数,其中唯一的区别是行if (data[0] > colour) {大于或小于。

10 个答案:

答案 0 :(得分:2)

如何将条件函数作为第三个参数传递?

function getEdges(colour, condition) {
    for (let x = 0; x < width; x++) {
        for (let y = height - 1; y >= 0; y--) {
            const data = getData(x,y);
            if (condition(data[0], colour)) {
                edge.push(y);
                break;
            }
        }
    }
    return edge;
}

调用该函数并传递所需条件。

  • 小于:getEdges(color, (data, color) => color < data);

  • 大于:getEdges(color, (data, color) => color > data);

答案 1 :(得分:2)

如果两个函数之间的唯一区别是比较,那么您可以提取它并将其作为参数

function getEdges(colour, comparator) {
  for (let x = 0; x < width; x++) {
    for (let y = height - 1; y >= 0; y--) {
      const data = getData();
      if (comparator(data[0], colour)) {
        edge.push(y);
        break;
      }
    }
  }
  return edge;
}

//call with less than
getEdges(someColour, (a, b) => a < b)
//call with greater than
getEdges(someColour, (a, b) => a > b)

您还可以将逻辑保留在一个函数中,并从中导出另外两个逻辑。这样,您无需维护多个代码块,仍然可以得到两个显式调用:

通过.bind使用部分应用程序:

function getEdges(comparator, colour) {
//                    ^        ^      the two parameters are swapped
  for (let x = 0; x < width; x++) {
    for (let y = height - 1; y >= 0; y--) {
      const data = getData();
      if (comparator(data[0], colour)) {
        edge.push(y);
        break;
      }
    }
  }
  return edge;
}

//partial application
const getEdgesLessThan = getEdges.bind(null, (a, b) => a < b);
const getEdgesGreaterThan = getEdges.bind(null, (a, b) => a > b);

getEdgesLessThan(someColour)
getEdgesGreaterThan(someColour)

使用a curried function

function getEdges(comparator) {
//                    ^---------
  return function(colour) {//  | taking two parameters
//                  ^ ----------
    for (let x = 0; x < width; x++) {
      for (let y = height - 1; y >= 0; y--) {
        const data = getData();
        if (comparator(data[0], colour)) {
          edge.push(y);
          break;
        }
      }
    }
    return edge;
  }
}

//currying
const getEdgesLessThan = getEdges((a, b) => a < b);
const getEdgesGreaterThan = getEdges((a, b) => a > b);

getEdgesLessThan(someColour)
getEdgesGreaterThan(someColour)

答案 2 :(得分:1)

  

编辑:要清楚,在理想的世界中,我想这样做:

myFunction(10, 5, >)

您可以获得类似的东西:

const lt = (x, y) => x < y;
const gt = (x, y) => x > y;

function foo(value, modifier, compare) {
    let result;
    if (compare(value, modifier)) result = 10;
    return result;
}

console.log(foo(2, 3, lt)); // 10
console.log(foo(3, 2, gt)); // 10

使用第二个示例:

const lt = (x, y) => x < y;
const gt = (x, y) => x > y;

const width  = 3;
const height = 3;

const getData = (x, y) => [height * x + y];

console.log(getEdges(3, lt)); // [2]
console.log(getEdges(3, gt)); // [2,2]

function getEdges(colour, compare) {
    const edge = [];

    for (let x = 0; x < width; x++) {
        for (let y = height - 1; y >= 0; y--) {
            const data = getData(x, y);

            if (compare(data[0], colour)) {
                edge.push(y);
                break;
            }
        }
    }

    return edge;
}

希望有帮助。

答案 3 :(得分:1)

基于评论中的对话,目的是在需要大于或小于比较时重新使用getEdges函数。我添加了第二个参数来表明这一点,默认情况下将其设置为false。 if语句是双重用途的,即在isGreater标志设置为true时,它大于比较,而在isGreater标志设置为false中,则小于比较。 。其余逻辑按原样重复使用,没有重复。

function getEdgesInner(colour, isGreater = false) {
    for (let x = 0; x < width; x++) {
        for (let y = height - 1; y >= 0; y--) {
            const data = getData(x,y);
            if ((isGreater && data[0] > colour) || (!isGreater && data[0] < colour))
                edge.push(y);
                break;
            }
        }
    }
    return edge;
}

/* Public Api */
function getGreaterEdges(colour) { return getEdges(colour) }
function getLesserEdges(colour) { return getEdges(colour, true) }

答案 4 :(得分:1)

您可以保留运营商,并根据需要交换条款:

function getEdges(colour, operator) {
    for (let x = 0; x < width; x++) {
        for (let y = height - 1; y >= 0; y--) {
            const data = getData();
            const [a, b] = operator == '<' ? [data[0], colour] : [colour, data[0]];
            if (a < b) {
                edge.push(y);
                break;
            }
        }
    }
    return edge;
    }

编辑:

好,因此,如果您想使事情简单且在单独的函数中进行,只需对代码进行最少的更改,就可以像这样实现它:

function getEdges(colour, operator = '<') {
    for (let x = 0; x < width; x++) {
        for (let y = height - 1; y >= 0; y--) {
            const data = getData();
            const [a, b] = operator == '<' ? [data[0], colour] : [colour, data[0]];
            if (a < b) {
                edge.push(y);
                break;
            }
        }
    }
    return edge;
    }

签名getEdges(colour, operator = '<')使operator参数成为可选参数。如果您不将其传递给函数,它将采用默认值'<',这样您就不必在现有代码中进行任何更改。然后,您可以创建第二个函数,仅使用一个不同的参数即可重复使用原始函数:

function getEdgesGreaterThan(colour) {
    return getEdges(colour, '>');
}

就在那里!希望对您有帮助!

答案 5 :(得分:1)

您可以尝试以下方式。就像您想要的原始样品一样!具有简短,时尚和美观的想法

数学技巧:

function func(value, modifier, sign) {
 let result, fc=sign=="<"?1:-1;
 if (value*fc< modifier*fc) result = 10;
 return result; 
}

一个有用的JS功能:

function func(value, modifier, sign) {//this is slower probably
 let result; 
 if (eval(value+sign+modifier)) result = 10;
 return result; 
}

用法(双向):

console.log(func(1, 2, "<"));

传递委托函数(用于比较):

function func(value, modifier, compF) {
 let result; 
 if (compF(value, modifier)) result = 10;
 return result; 
}

用法:

console.log(func(1, 2, function(v, m){return v<m;}/*or equivalent lambda function*/));

答案 6 :(得分:0)

您应该添加带有条件的第三个参数,例如,字符串“ gt”表示Grater Than(>),“ lt”表示小于Than(<)

function(value, modifier, cond){
   if(cond === "gt") return value > modifier ? 10 : undefined;
   else if(cond === "lt") return value < modifier ? 10 : undefined; 
}

编辑:我想出了一个更好的解决方案,适合您的最新问题。

let check = (value, modifier, cond)=>eval(value + cond + modifier) ? 10 : undefined

您在此处传递"<"参数的">"cond

编辑2:

function getEdges(colour,cond) {
for (let x = 0; x < width; x++) {
    for (let y = height - 1; y >= 0; y--) {
        const data = getData(x,y);
        let shoudPush = eval(data[0] + cond + colour) ? true : false
        if(shouldPush) {
          edge.push(y); 
          break;
        }
    }
}
return edge;
}

答案 7 :(得分:0)

function(value, modifier, type) {
    let result;
    if(type == ">") {
        if (value > modifier) result = 10;
    } else {
        if (value < modifier) result = 10;
    }
    return result;
}

并通过字符串“ <”或“>”

传递类型

答案 8 :(得分:0)

  

编辑:要清楚,在理想的世界中,我想这样做:

myFunction(10, 5, >)

您几乎可以使用eval做到这一点。尽管我对您的result有点困惑,因为它可能返回未定义的值。

var myFunction = function(value, modifier, operation) {
    var evalResult = eval(value + operation + modifier)
    // I like ternary expression but could also be written as an if/else statement 
    return evalResult ? 10 : undefined
}
myFunction(10, 5, '<') // outputs undefined
myFunction(10, 5, '>') // outputs 10

请注意,评估可能很危险。 https://medium.com/@eric_lum/the-dangerous-world-of-javascripts-eval-and-encoded-strings-96fd902af2bd

编辑 嘿,我对您编辑的答案做了一个Codepen。 https://codepen.io/springborg/pen/ydayYa

我认为这与您建议的语法最接近。尽管除非您绝对确定不会暴露任何漏洞,否则我可能建议不要使用eval。

我的建议是使用Aditya Bhave的答案:) https://stackoverflow.com/a/56649540/1303205

答案 9 :(得分:0)

如果可重用性是您的最终目标,那么下面是一个很好的例子,说明了如何实现可重用性(某种功能编程风格)。

这种方法可以更大程度地重用代码。您可能希望在代码中的两点进行比较,然后根据上下文返回不同的值。

let functionalComparer = comp => modifier => result => value => {
  return comp(value, modifier) ? result: undefined
}

// curry the crap out of it!
let gt = (x,y) => x > y
let gtComp = functionalComparer(gt)
let gt100 = gtComp(100)
let whenGt100ReturnString = gt100("more than 100!")

console.log(`
  with value 99: ${whenGt100ReturnString(99)},
  with value 101: ${whenGt100ReturnString(101)}
`)

let lt = (x,y) => x < y
let whenLt50ReturnFoo = functionalComparer(lt)(50)("FOO")

console.log(`
  with value 49: ${whenLt50ReturnFoo(49)},
  with value 51: ${whenLt50ReturnFoo(51)}
`)

相关问题