我坚持严格的函数式编程原则,没有变异。
如何以不会使greeting
变量变异的方式编写类似下面代码的内容,而不在每个if
块中返回它?
const greet = (name, time) => {
let greeting = 'Morning';
if(time >= 12) {
greeting = 'Afternoon';
}
if(time >= 17) {
greeting = 'Evening';
}
return `Good ${greeting} ${name}!`;
};
如果只是两个条件,我会做以下事情,但是当有3个条件时它不会起作用:
const greeting = time > 12 ? 'Afternoon' : 'Morning'
答案 0 :(得分:11)
Ternary expressions可以组成其他三元表达式 - 允许我们对逻辑选择进行排序
private void runCMDFile()
{
string path = @"C:\Users\username\Desktop\yourFile.cmd";
Process proc = new Process();
proc.StartInfo.FileName = path;
proc.StartInfo.UseShellExecute = true;
proc.StartInfo.CreateNoWindow = false;
proc.StartInfo.RedirectStandardOutput = false;
proc.StartInfo.Verb = "runas";
proc.Start();
proc.WaitForExit();
}
但是,我认为变量使变量成为变量 ...
你有两个担忧,并且将它们分开来帮助你
通过这样做,你可以避免
const greeting = time > 12 ? (time > 17 ? 'Evening' : 'Afternoon') : 'Morning'
的本地重新分配)greeting
,let
,if
,return
)结果是使用表达式编写的两个纯(referentially transparent)函数 - 没有赋值(或重新赋值),并且没有副作用。
x = ...

答案 1 :(得分:7)
WITH date1 AS (
SELECT to_date('2017-07-26 02:37:00 AM','yyyy-MM-dd hh12:mi:ss am') dt2,
to_date('2017-07-26 06:10:00 PM','yyyy-MM-dd hh12:mi:ss am') dt1 FROM DUAL
)
select TO_CHAR (greatest(dt2, trunc(dt2+(level-1)/24, 'hh24')),
'dd-MON-yyyy HH12:MI:SS AM') FROM_DT,
TO_CHAR ( least(dt1, trunc(dt2+(level)/24, 'hh24'),
'dd-MON-yyyy HH12:MI:SS AM') TO_DT
from date1 connect by level <= floor(
(trunc(dt1,'HH')-trunc(dt2,'HH')) *24) + case when (
dt1 <> trunc(dt1,'HH')
) then 1 else 0 end
从技术上讲,这使您可以灵活地在将来添加更多时间,例如在第12小时添加const greeting = [
'Morning', 'Morning', 'Morning', 'Morning', 'Morning', 'Morning', 'Morning',
'Morning', 'Morning', 'Morning', 'Morning', 'Morning',
'Afternoon', 'Afternoon', 'Afternoon', 'Afternoon', 'Afternoon',
'Evening', 'Evening', 'Evening', 'Evening', 'Evening', 'Evening', 'Evening'
]
return `Good ${greeting[time]} ${name}!`
。此外,由于类似的原因,它使本地化更容易;某些区域设置可能有'Noon'
个其他区域可能没有。
这原本是个笑话;)
答案 2 :(得分:2)
这个问题已经回答了,但如果你有3个以上的选择,你可以这样做:
['Evening', 'Afternoon', 'Morning']
[
[17,12,0].findIndex((el) => time >= el)
]
答案 3 :(得分:2)
(function (){
const greet = (name, time) => {
const greetings = [ // Order is important
{greeting: 'Evening',time: 17},
{greeting: 'Afternoon',time: 12},
{greeting: 'Morning',time: -Infinity}
];
const greeting = greetings.find(e=>time>=e.time).greeting;
return `Good ${greeting} ${name}!`;
}
console.log(greet('Me',17));
})();
答案 4 :(得分:1)
要清楚你没有做任何突变,你使用let而不是const。为什么它不是变异 - 因为字符串在javascript中是不可变的。所以你的问题更多 - &#34;如何将条件值分配给const&#34;。
要明确我在这里做让这样的行为并没有发现任何问题。除非这不在函数范围之外,否则改变它就好了(我正在谈论更多关于一般方法,例如对象)。
不变性规则应该用于在函数范围之外声明的结构。什么直接意味着你永远不应该改变功能输入,永远不要触摸不属于你的东西。
到目前为止,我的答案是 - 保持原样,对我而言,它比具有许多条件的三元运算符更清晰。
答案 5 :(得分:0)
在JavaScript中,变量本质上不能成为不可变的。但是,您可以使用字符串值或声明常量来使用不可变表达式。该解决方案依赖于三个常量。一个常量是一个对象,其中包含与24小时时间跨度中的三个周期相对应的字符串值。第二个常量保存测试时间(tod)的结果。并且,最后一个常量包含函数表达式,即匿名函数,如下所示:
let d = new Date();
let time = d.getHours();
const greeting = {
"morn": "morning",
"after": "afternoon",
"evg": "evening"
};
const greet = function(strName) {
const tod = (time < 12) ? greeting["morn"] :
(time > 17) ? greeting["evg"] : greeting["after"];
let salutation = "Good " + tod;
salutation += ",";
strName += "!";
// adding another functional programming touch
return function() {
console.log([salutation, strName].join(" "));
};
};
var user = "Zander";
greet(user)();
&#13;
请注意,虽然字符串值是不可变的,但String对象本身是可变的。您可以向该对象添加属性,您可以更改该属性的值;参见示例here。
使用关键字const创建一个常量,并按MDN:
常量的值不能通过重新赋值来改变 不能重新宣布。
在这个和其他例子中,根据一天三次表达的时间设定常数,常数本身是变量&#34;如果它的值根据脚本运行的时间而变化。