函数式编程

article/2025/10/19 22:01:42

Functional Programming

什么是函数式编程

函数式编程的思维方式:把显示世界的事务和事物之间的联系抽象到程序世界(对运算过程进行抽象)

  • 函数式编程中的函数指的数学中的函数即映射关系,输入的值对应一个输出的值,例如 y = f(x)
  • 相同的输入始终得到相同的输出(纯函数)
  • 函数式编程用来描述数据(函数)之间的映射
// 非函数式
const num1 = 2
const num2 = 3
const sum = num1 + num2
console.log(sum)// 函数式
function add(n1, n2) {return n1 + n2
}const sum = add(2, 3)
console.log(sum)

前置知识

函数式一等公民(头等函数)

MDB First-class Function

  • 函数可以存储在变量中
  • 函数作为参数
  • 函数作为返回值

在 javascript 中函数就是一个普通对象(可以通过 new Function()),可以把函数存储到变量或者数组中,
还可以当成另外一个函数的参数和返回值,甚至可以在程序运行的时候通过new Function('alter(1)')来构造一个新的函数。

  • 把函数复制给变量
const fn = function () {console.log('this is a function')
}fn()// 一个示例
const BlogController = {index(posts) {return Views.index(posts)},show(post) {return Views.show(post)},create(attrs) {return Db.create(attrs)},update(post, attrs) {return Db.update(post, attrs)},destroy(post) {return Db.destroy(post)}
}// 优化
const BlogController = {index: Views.index,show: Views.show,create: Db.create,update: Db.update,destroy: Db.destroy
}

高阶函数

什么是高阶函数

  • 高阶函数(Higher-order function)
    • 可以把函数作为参数传递给另一个函数
    • 可以把函数作为另一个函数的返回值
  • 函数作为参数
function forEach(array, fn) {for (let i = 0; i < array.length; i++) {fn(array[i])}
}function filter(array, fn) {const result = []for (let i = 0; i < array.length; i++) {if (fn(array[i])) {result.push(array[i])}}return result
}const a = [1, 2, 3, 4, 5]forEach(a, v => {console.log(v)
})const result = filter(a, v => {return v % 2 === 0
})
console.log(result)
  • 函数作为返回值
function makeFn() {const msg = 'Hello Function'return function () {console.log(msg)}
}const fn = makeFn()
fn()
// 或者
makeFn()()// once 函数
function once(fn) {let done = falsereturn function () {if (!done) {done = truereturn fn.apply(this, arguments)}}
}const onceFn = once(function (msg) {console.log(msg)
})onceFn('run once')
onceFn('run once')
onceFn('run once')
onceFn('run once')

使用高阶函数的意义

  • 抽象可以屏蔽细节,只需要关注目标
  • 高阶函数式用来抽象通用问题

// 面向过程的方式
const arr = [1, 2, 3, 4]for (const i of arr) {console.log(i)
}// 高阶函数const arr = [1, 2, 3, 4]// 前面定义的函数
forEach(arr, item => {console.log(item)
})

常用的高阶函数

  • forEach
  • map
  • filter
  • every
  • some
  • find/findIndex
  • reduce
  • sort
const map = (arr, fn) => {const result = []for (const value of arr) {result.push(fn(value))}return result
}const every = (arr, fn) => {let result = truefor (const value of arr) {result = fn(value)if (!result) {break}}return result
}const some = (arr, fn) => {let result = falsefor (const value of arr) {result = fn(value)if (result) {break}}return result
}

闭包

  • 闭包(Closure):函数和其周围的状态(词法环境)的引用捆绑在一起形成闭包。
    • 可以在另一个作用域中调用一个函数的内部函数并访问该函数的作用域中的成员
  • 闭包的本质:函数在执行的时候会放到一个执行栈上,当函数执行完毕之后会从执行栈上移除,但是堆上的作用域成员因为
    被外部引用不能释放,因此内部函数依然可以访问外部函数的成员
  • 闭包案例
function makePower(power) {return function (x) {return Math.pow(x, power)}
}const power2 = makePower(2)
const power3 = makePower(3)console.log(power2(2))
console.log(power2(3))
console.log(power3(2))

纯函数

纯函数概念

  • 纯函数:相同的输入永远会得到相同的输出,而且没有任何可观察的副作用
    • 纯函数类似数学中的函数(用来描述输入和输出之间的关系),y = f(x)
  • 数组的 slicesplice 分别是:纯函数和不纯的函数
    • slice 返回数组中的指定部分,不会改变原数组
    • splice 对数组进行操作返回该数组,会改变原数组
let numbers = [1, 2, 3, 4, 5]
// 纯函数
numbers.slice(0, 3)
// => [1, 2, 3]
numbers.slice(0, 3)
// => [1, 2, 3]
numbers.slice(0, 3)
// => [1, 2, 3]// 不纯的函数
numbers.splice(0, 3)
// => [1, 2, 3]
numbers.splice(0, 3)
// => [4, 5]
numbers.splice(0, 3)
// => []
  • 函数式编程不会保留计算中间的结果,所以变量是不可变的(无状态的)
  • 可以把一个函数的执行结果交给另一个函数去处理

纯函数的好处

  • 可缓存
    • 纯函数对相同的输入始终有相同的结果,所以可以把纯函数的结果缓存起来
  • lodash memoize
const _ = require('lodash')function getArea(r) {console.log('running')return Math.PI * r * r
}const getAreaWithMemory = _.memoize(getArea)console.log(getAreaWithMemory(4))
console.log(getAreaWithMemory(4))
console.log(getAreaWithMemory(4))
  • 手动模拟
function memoize(fn) {const cache = {}return function () {const key = JSON.stringify(arguments)cache[key] = cache[key] || fn.apply(fn, arguments)return cache[key]}
}
  • 可测试
    • 纯函数测试更方便
  • 并行处理
    • 在多线程环境下并行操作共享的内存数据很有可能会出现意外情况
    • 纯函数不需要访问共享的内存数据,所以在并行环境下可以任意运行纯函数(Web Worker)

副作用

  • 纯函数: 对于相同的输入永远会得到相同的输出,而且没有任何可观察的副作用
// 不纯的函数
const mini = 18function checkAge(age) {return age >= mini
}// 纯函数(但是有硬编码,不方便扩展)
function checkAge(age) {const mini = 18return age >= mini
}

如果函数依赖于外部的状态就无法保证输出相同,就会带来副作用。 副作用来源:

  • 配置文件
  • 数据库
  • 用户输入

所有的外部交互都有可能带来副作用,副作用也使得方法通用性下降不适合扩展和可重用性,同时副作
用会给程序中带来安全隐患给程序带来不确定性,但是副作用不可能完全禁止,尽可能控制它们在可控 范围内发生。

柯里化(Haskell Brooks Curry)

  • 柯里化(Currying):
    • 当一个函数有多个参数的时候先传递一部分参数调用它(这部分参数以后永远不变)
    • 然后返回一个新的函数接受剩余的参数,返回结果
function checkAge(age) {let min = 18return age >= min
}// 普通纯函数
function checkAge(min, age) {return age >= min
}// 柯里化,函数闭包
function checkAge(min) {return function (age) {return age >= min}
}// ES6 写法
const checkAge = min => age => age >= minconst checkAge18 = checkAge(18)
const checkAge22 = checkAge(22)checkAge18(20)
checkAge22(20)

lodash 中的柯里化函数

  • _.curry(func)
  • 功能:创建一个函数,该函数接受一个或者多个 func 的参数,如果 func 所需要的参数都被提供 则执行 func
    并返回执行的结果。否则继续返回该函数并等待接受剩余的参数。
  • 参数:需要柯里化的函数
  • 返回值:柯里化后的函数
const _ = require('lodash')// 需要柯里化的函数
function getSum(a, b, c) {return a + b + c
}// 柯里化后的函数
const curried = _.curry(getSum)// 多种使用方式
curried(1, 2, 3)
curried(1, 2)(3)
curried(1)(2, 3)
curried(1)(2)(3)
  • 案例

查找字符数组中带有空格的项

const _ = require('lodash')// 柯里化后的函数
const match = _.curry(function (reg, str) {return str.match(reg)
})// 接受了一个参数
const haveSpace = match(/\s+/g)
const haveNumber = match(/\d+/g)// 传入剩余参数
console.log(haveSpace('hello world'))
console.log(haveNumber('23$'))// 柯里化后的函数
const filter = _.curry(function (func, arr) {return arr.filter(func)
})// 传入全部的参数
console.log(filter(haveSpace, ['Hello World', 'hello_wordl']))// 传入一个参数
const findSpace = filter(haveSpace)// 传入剩余的参数
console.log(findSpace(['hello world', 'hello_world']))
  • 模拟 _.curry() 的实现

// 参数为需要柯里化的函数
function curry(fn) {// 返回的函数需要接受剩余的参数return function curryFn(...args) {// 如果传入的参数和函数的参数长度不一致if (fn.length > args.length) {// 继续返回一个函数,多次柯里化return function () {// 将闭包中的 args 和传入的参数合并,argumentsreturn curryFn(...args.concat(Array.from(arguments)))}}// 返回执行后的值return fn(...args)}
}

总结

  • 柯里化可以让我们给一个函数传递较少的参数得到一个已经记住了某些固定参数的新函数
  • 这是一种对函数参数的缓存
  • 让函数变得更灵活,让函数的粒度更小
  • 可以把多元函数转为一元函数,可以组合使用函数产生强大的功能(一个参数的函数成为一元函数,类似数学的函数)

函数组合

  • 纯函数和柯里化很容易写出洋葱代码h(g(f(x)))
    • 获取数组的最后一个元素再转成大写字母,_.toUpper(_.first(_.reverse(arr)))
image-20211211102956846
  • 函数组合可以让我们把细粒度的函数重新组合生成一个新的函数

管道

下面这张图表示程序中使用函数处理数据的过程,给 fn 函数输入参数 a,返回结果 b。可以想想 a 数据 通过一个管道得到了 b 数据。

image-20211211103212323

当 fn 函数比较复杂的时候,我们可以把函数 fn 拆分成多个小函数,此时多了中间运算过程产生的 m 和 n。

下面这张图中可以想象成把 fn 这个管道拆分成了3个管道 f1, f2, f3,数据 a 通过管道 f3 得到结果 m,m 再通过管道 f2 得到结果 n,n
通过管道 f1 得到最终结果 b

image-20211211103248191

fn = compose(f1, f2, f3)
result = fn(value)

函数组合

  • 函数组合(compose):如果一个函数要经过多个函数处理才能得到最终值,这个时候可以把中间的过程的 函数合并成一个函数
    • 函数就像是数据的管道,函数组合就是把这些管道连接起来,让数据穿过多个管道形成最终结果
    • 函数组合默认是从右到左执行
// 基本函数组合
function compose(f, g) {return function (x) {return f(g(x))}
}function first(arr) {return arr[0]
}function reverse(arr) {return arr.reverse()
}const last = compose(first, reverse)console.log(last([1, 2, 3, 4]))
  • lodash 中的组合函数
  • lodash 中阻焊函数 flow() 从左到右或者 flowRight() 从右到左
const _ = require('lodash')const toUpper = s => s.toUpperCase()
const reverse = arr => arr.reverse()
const first = arr => arr[0]// 获取数组最后一个值,并转为大写
const f = _.flowRight(toUpper, first, reverse)
console.log(f(['one', 'tow', 'three']))
  • 模拟 lodash 的 flowRight 方法
// 接受多个函数
function compose(...fns) {// 传入的值return function (value) {// 使用 reverse 将函数从右到左执行,使用 reduce 把执行结果进行累加return fns.reverse().reduce(function (acc, fn) {return fn(acc)// 累加初始值为 value}, value)}
}// ES6 写法
const compose = (...fns) => value => fns.reverse().reduce((acc, fn) => fn(acc), value)
  • 函数的组合要满足结合律(associativity):
    • 可以把 g 和 h 组合,还可以把 f 和 g组合,结果都是一样的
// 结合律
const fn = compose(f, g, h)const fnAssociative = compose(compose(f, g), h) === compose(f, compose(g, h))
  • 所以代码可以这样结合
const _ = require('lodash')const f = _.flowRight(_.toUpper, _.first, _.reverse)
const f = _.flowRight(_.flowRight(_.toUpper, _.first), _.reverse)
const f = _.flowRight(_.toUpper, _.flowRight(_.first, _.reverse))
console.log(f(['one', 'tow', 'three'])) // THREE

函数组合打印日志

const _ = require('lodash')const trace = _.curry((tag, value) => {console.log(value, tag)return value
})// 使用柯里化,使得函数可以传递部分参数,加上函数组合为更强大的函数
// lodash 模块都是值在前,fn 在后的形式
const split = _.curry((sep, str) => _.split(str, sep))
const join = _.curry((sep, arr) => _.join(arr, sep))
const map = _.curry((fn, arr) => _.map(arr, fn))const f = _.flowRight(join('-'), trace('map'), map(_.toLower), trace('split'), split(' '))
console.log(f('NEVER SAY DIE')) // never-say-die
  • lodash/fp
    • lodash 的 fp 模块提供了实用的对函数式编程友好的方法
    • 提供了不可变 auto-curried iteratee-first data-last 的方法
const _ = require('lodash')
_.map(['a', 'b', 'c'], _.toUpper)
// => ['A', 'B', 'C']
_.map(['a', 'b', 'c'])
// => ['a', 'b', 'c']_.split('hello world', ' ')const fp = require('lodash/fp')// fp 模块下的函数都是柯里化后的函数
// 可以传递部分参数生成一个新的函数
// 获取全部参数可以得到返回结果
// 全部参数
fp.map(fp.toUpper, ['a', 'b', 'c'])
// 部分参数,生成了一个新的函数,再次调用
fp.map(fp.toUpper)(['a', 'b', 'c'])
fp.split(' ', 'hello world')
fp.split(' ')('hello world')const f = fp.flowRight(fp.join('-'), fp.map(fp.toLower), fp.split(' '))
console.log(f('NEVER SAY DIE'))

Point Free Programming

Point Free: 可以把数据处理的过程定义成与数据无关的合成运算,不需要用到代表数据的那个参数
只要把简单的运算步骤合成到一起,在使用这种模式之前我们需要定义一些辅助的基本运算函数。

  • 不需要知名处理的数据
  • 只需要合成运算的过程
  • 需要定义一些辅助的基本运算函数
const f = fp.flowRight(fp.join('-'), fp.map(fp.toLower), fp.split(' '))
  • 案例演示
// 非 Point Free 模式
// Hello World => hello_world
function f(word) {return word.toLowerCase().replace(/\s_/g, '_')
}// Point Free
const fp = require('lodash/fp')// 合成运算
const f = fp.flowRight(fp.replace(/\s+/g, '_'), fp.toLower)console.log(f('Hello World'))

Functor(函子)

why

需要把函数式编程中的副作用控制在可控的范围内、异常处理和异步操作等。

what

  • 容器:包含值和值的变形关系(这个变形关系就是函数)
  • 函子:是一个特殊的容器,通过一个普通的对象来实现,该对象具有map方法,map方法可以运行一个 函数对值进行处理(变形关系)

Functor 函子

// 一个容器,包裹一个值
class Container {constructor(value) {this._value = value}// 静态方法,可以屏蔽 new 关键字创建对象static of(value) {return new Container(value)}// map 方法,传入变形关系,将容器里的值映射到另外一个容器map(fn) {return new Container(fn(this._value))}
}// 链式调用
Container.of(3).map(v => v + 1).map(v => v ** 2)
  • 函数式编程的运算不直接操作值,而是由函子完成
  • 函子就是一个实现了 map 契约的对象
  • 可以把函子想象成一个盒子,这个盒子里封装了一个值
  • 想要处理盒子中的值,需要给盒子的 map 方法传递一个处理值的函数(纯函数),由这个函数来对值进行处理
  • 最后 map 方法返回一个包含新值的盒子(函子)

如果 Functor 中传入 null 或者 undefined

// 如果传入 null, 会报错
Container.of(null).map(x => x.toUpperCase())
// TypeError: Cannot read property 'toUpperCase' of null

MayBe 函子

  • 编程的过程中可能会遇到很多错误,需要对这些错误做响应的处理
  • MayBe 函子的作用就是可以对外部的控制情况做处理(控制副作用在允许的范围)
// 基本结果和上面一样
class MayBe {constructor(value) {this._value = value}static of(value) {return new MayBe(value)}map(fn) {// 新增对 _value 值的判断,判断不通过则返回 nullreturn this.isNothing() ? MayBe.of(null) : MayBe.of(fn(this._value))}// 新增对值的判断isNothing() {return this._value === null || this._value === undefined}
}// 传入具体值 
MayBe.of('Hello World').map(x => x.toUpperCase())
// 传入 null 的情况 
MayBe.of(null).map(x => x.toUpperCase())
// => MayBe { _value: null }
  • 在 MayBe 函子中,很难确定在哪一步产生的空值问题,如下:
MayBe.of('hello').map(v => v.toUpperCase()).map(v => null).map(v => x.split(' '))
// => MayBe { _value: null }

Either 函子

  • Either 两者中的任务一个,类似于 if … else … 的处理
  • 异常会让函数变得不纯, Either 函子可以用来做异常处理
class Left {constructor(value) {this._value = value}static of(value) {return new Left(value)}map(fn) {// Left 处理异常信息,不对值进行改变return this}
}class Right {constructor(value) {this._value = value}static of(value) {return new Right(value)}map(fn) {return Right.of(fn(this._value))}
}
  • Either 用来处理异常
function parseJSON(str) {try {return Right.of(JSON.parse(str))} catch (e) {// 异常会让函数不纯,使用 Left 来统一获取异常消息return Left.of({error: e.message})}
}const result = parseJSON('{"age": 1}').map(x => x >= 18)
console.log(result)

IO 函子

  • IO 函子中的 _value 是一个函数,这里把函数作为值来处理
  • IO 函子可以把不纯的动作存储到 _value 中,延迟这个不纯的操作(惰性执行),保证当前的操作纯
  • 把不纯的操作交给调用者来处理
const fp = require('lodash/fp')class IO {// 构造函数传入一个函数constructor(fn) {this._value = fn}static of(value) {return new IO(function () {return value})}map(fn) {// 把当前的 _value 和传入的 fn 组合成一个新的函数return new IO(fp.flowRight(fn, this._value))}
}const io = IO.of(process).map(p => p.execPath)
console.log(io._value())

Task 异步执行

  • folktale(2.3.2)
const {task} = require('folktale/concurrency/task')// 类似后面的 Promise
function readFile(filename) {return task(resolver => {fs.readFile(filename, 'utf-8', (err, data) => {if (err) {resolver.reject(err)}resolver.resolve(data)})})
}// 调用 run 执行
readFile('../package.json').map(split('\n')).map(find(x => x.includes('version'))).run().listen({onRejected: err => {console.log(err)},onResolved: value => {console.log(value)}})

Pointed 函子

  • Pointed 函子是实现了 of 静态方法的函子
  • of 方法是为了避免使用 new 来创建对象,更深层次的含义是 of 方法用来把值放到上下文 Context (把值放到容器中,使用 map 来处理值)

image-20211211182414089

class Container {static of(value) {return new Container(value)}// ...
}Container.of(2).map(x => x + 5)

Monad (单子)

在使用 IO 函子的时候,如果写出如下代码:

const fs = require('fs')
const fp = require('lodash/fp')
const readFile = function (filename) {return new IO(() => {return fs.readFileSync(filename, 'utf-8')})
}const print = function (value) {return new IO(() => {console.log(value)return value})
}const cat = fp.flowRight(print, readFile)
const r = cat('../package.json')._value()._value()
console.log(r)
  • Monad 函子是可以变扁的 Pointed 函子, IO(IO(x))
  • 一个函子如果具有 join 和 of 两个方法并遵守一些定律就是一个 Monad
const fp = require('lodash/fp')class IO {constructor(fn) {this._value = fn}static of(value) {return new IO(() => {return value})}map(fn) {return new IO(fp.flowRight(fn, this._value))}join() {return this._value()}flatMap(fn) {return this.map(fn).join()}
}const r = readFile('../package.json').map(fp.toUpper).flatMap(print).join()

http://chatgpt.dhexx.cn/article/WZrINckc.shtml

相关文章

appium环境搭建python_appium环境搭建python

1&#xff0c;appium是开源的移动端自动化测试框架&#xff1b;2&#xff0c;appium可以测试原生的、混合的、以及移动端的web项目&#xff1b;3&#xff0c;appium可以测试ios&#xff0c;android应用(当然了&#xff0c;还有firefox os)&#xff1b;4&#xff0c;appium是跨平…

Windows下Appium环境搭建小结

文章目录 Windows下Appium环境搭建小结需要安装的软件1. JDK下载安装/配置 2. Android SDK3. Maven下载安装/配置 4. Appium下载安装/配置 5. Eclipse TestNG 和 ADT 插件下载安装一条龙配置1、先配置Maven 创建一个项目 Windows下Appium环境搭建小结 本文需要读者已安装了Ec…

Mac端Python+Appium环境搭建

一、安装java sdk java安装&#xff1a;下载完直接安装jdk1.8 二、 安装Android Studio 1.下载安装 下载地址&#xff1a;https://www.androiddevtools.cn/# 2.安装完成后&#xff0c;打开SDK Manager 三、JAVA SDK和Android SDK环境变量配置 1.终端输入&#xff1a;ls…

安卓移动端appium环境搭建流程

安卓移动端appium环境搭建流程 基本步骤: 安装Node.js 安装JDK&#xff0c;及配置环境变量 安装SDK&#xff0c;及配置环境变量 安装Appium桌面版本(建议安装GitHub的最新版) python中pip下载Appium-Python-Client 下载allure-2.13.8并加入环境变量 管理员身份运行appiu…

pythonappium环境搭建_python+appium 环境搭建

最近学习了一下python语言&#xff0c;听说appium是做app的ui层的自动化的一个很好的框架&#xff0c;也是很多人在学习的框架&#xff0c;所以很感兴趣&#xff0c;也特意来学习一下&#xff0c;下面是我学习过程的一些心得和总结&#xff0c;希望对大家有所帮助。 一、环境搭…

Appium环境搭建(集齐Windows和MacOS的宝藏内容)

Appium环境搭建目录 Windows系统环境下安装Node.js安装JDK及环境变量配置添加环境变量 安装SDK添加环境变量 安装Appium可通过三种方法安装安装 **appium-doctor** MacOS系统环境下安装xcode安装依赖安装WebDriverAgent运行WebDriverAgent windows 安装 tidevice常用的tidevice…

mac appium环境搭建

appium环境的搭建其实也不复杂&#xff0c;主要是配置的比较多&#xff0c;只是在配置的过程中&#xff0c;根据当时的机器配置会遇到一些具体问题&#xff0c;一个个解决就可以了。 安装下面这篇文章搭建就可以了 超详细的Mac下appium环境搭建 配置java环境有问题&#xff0c;…

pythonappium环境搭建_python appium环境搭建

1&#xff0c;appium是开源的移动端自动化测试框架&#xff1b; 2&#xff0c;appium可以测试原生的、混合的、以及移动端的web项目&#xff1b; 3&#xff0c;appium可以测试ios&#xff0c;android应用&#xff08;当然了&#xff0c;还有firefox os&#xff09;&#xff1…

Appium 环境搭建

一、下载并安装appium客户端(勿装1.15.1版本,1.15.1版本很多坑) 进入appium官网http://appium.io/下载版本&#xff0c;将下载好的版本按照步骤进行安装 Appium-Python-Client第三方包 pip3 install Appium-Python-Client -i https://pypi.tuna.tsinghua.edu.cn/simple 二…

appium环境搭建全套

环境 1 Node.js 2 Appium 3 Appium-desktop 4 Appium-Python-Client 5 Python 6 JDK 7 Andriod SDK 8 Appium-doctor 一、安装Node.js 下载地址&#xff1a;https://nodejs.org/en/download/releases/ 注意&#xff1a;Appium版本是1.7.2&#xff0c;则选择的No…

Appium环境搭建

一、Appium框架原理 1.介绍 appium是一个移动端的自动化测试框架&#xff0c;可用于测试原生应用&#xff0c;移动网页应用和混合应用&#xff0c;支持iOS和Android。 2.原理 appium可以理解为一个c/s架构软件&#xff0c;在pc端安装的appium server端&#xff0c;通过appi…

Appium环境搭建教程

最近打算研究开发一个手机的自动化小工具&#xff0c;奈何在这方面自己是一个小白&#xff0c;于是开始针对手机进行研究。由于主要使用Appium这个工具&#xff0c;因此本文主要讲解Appium环境的搭建&#xff0c;并结合自己的实践讲一讲需要避过的坑。 一、 安装Node.js Node.…

MySQL函数语句

目录 一、MySQL数据库函数作用二、MySQL数据库函数分类1.1.1、数学函数常用的数学函数1、abs(x)&#xff1a;返回x的绝对值2、rand() &#xff1a;返回0到1的随机数3、mod(x&#xff0c; y) &#xff1a;返回x除以y以后的余数4、power(x&#xff0c; y)“&#xff1a;返回x的y次…

MySQL函数(=)

1 将username字段的截取两个字符&#xff0c;其中将包含为1的字符替换为q SELECT REPLACE(SUBSTRING(username,1,2),1,q) FROM guanliyuan; 2 将日期时间转换为字符串 SELECT DATE_FORMAT(2009-10-11 22:12:12,%Y%m%d%H%i%s); 3 从日期中截取年份 SELECT SUBSTRING(DATE_FO…

MySQL函数介绍

MySQL数据库提供了很多函数包括&#xff1a; 数学函数&#xff1b;字符串函数&#xff1b;日期和时间函数&#xff1b;条件判断函数&#xff1b;系统信息函数&#xff1b;加密函数&#xff1b;格式化函数&#xff1b; 一、数学函数 数学函数主要用于处理数字&#xff0c;包括整…

mysql函数实例

红色为表名&#xff0c;蓝色为字段名&#xff0c;绿色为函数,可根据自己的情况修改 点击跳转mysql函数全集https://blog.csdn.net/qq_41738750/article/details/121003757https://blog.csdn.net/qq_41738750/article/details/121003757 教学视频http://121.4.59.101/2.mp4 一…

MySQL函数学习

目录 一、日期函数&#xff1a; 二、字符串函数学习 三、窗口函数 1.序号函数 ​2.开窗聚合函数 ​2.分布函数 3.前后函数 4.头尾函数 5.其他函数 一、日期函数&#xff1a; 1.日期、时间获取&#xff1a; select curdate();#当前日期&#xff1b; select current_d…

MySQL函数运用

目录 一&#xff0c;函数的定义 二&#xff0c;常用函数 三&#xff0c;字符串函数 四&#xff0c; 数学函数 五&#xff0c;判断函数 六、合并(union) 一&#xff0c;函数的定义 1.类似Java定义方法 2.可以带参数 3.必须有返回值(一行一列) &#xff0c;重点&#xff1a;ja…

MYSQL 函数

1.IF(Condition,A,B)Condition 为true 返回A 否则返回B 2.IFNULL(fieldA,fieldB)当字段fieldA是NULL时取fieldB&#xff0c;不是NULL时取fieldA的值nullif(exp1,exp2)如果exp1与exp2相等&#xff0c;则返回null&#xff0c;否则返回exp1 3.GROUP_CONCAT()该函数是将多条结果集变…

MySQL函数的使用

ABS(X) :返回x的绝对值 MOD(N,M):表示%,返回N被M除的余数 floor(X) :返回不大于X的最大整数值&#xff0c;向下取整 round(X) :四舍五入取整 distinct:distinct用于返回唯一不同的值。目的是去重 ifNull(X,Y)&#xff1a;查询时判断X是否为空,为空则使用默认值Y group_concat(X…