分享一些实用的PHP函数(对比js/ts实现)(1)

检查数组所有元素是否满足给定条件

如果提供的函数对数组的所有元素返回 true,则返回 true,否则返回 false

思路

实现思路如下:

使用数组的filter方法对数组执行给定的函数,然后使用count方法获取执行后的结果,再和count方法获取未执行filter方法的结果进行比较。

代码实现

下面我们来看php和js以及ts代码的实现:

php代码实现

php 复制代码
function all($arr,$fn){
    return count(array_filter($arr,$fn)) === count($arr);
}

使用示例

php 复制代码
all([2, 3, 4, 5], function ($item) {
  return $item > 1;
}); // true

js代码实现

js 复制代码
const all = (arr,fn) => arr.filter(fn).length === arr.length;

ts代码实现

ts 复制代码
const all = <T,U>(arr:T[], fn: (value: T, index: number, array: T[]) => U) => arr.filter(fn).length === arr.length;

使用示例

js 复制代码
all([2,3,4,5],n => n > 1); // true

总结

与js/ts实现不同点如下:

  1. php通过count方法来获取数组的长度,而js/ts则可以直接通过length来获取数组的长度。
  2. php的filter方法名叫array_filter,而js/ts则是叫filter

检查数组所有元素是否有一项满足给定条件

如果提供的函数对数组的至少一个元素返回 true,则返回 true,否则返回 false

实现思路

实现思路和前面的all函数很相似,只不过这里不需要做比较,只需要判断长度大于0即可。

代码实现

下面我们来看php和js以及ts代码的实现:

php代码实现

php 复制代码
function any($arr,$fn){
    return count(array_filter($arr,$fn)) > 0;
}

使用示例

php 复制代码
any([2, 3, 4, 5], function ($item) {
  return $item < 3;
}); // true

js代码实现

js 复制代码
const any = (arr,fn) => arr.filter(fn).length > 0;

ts代码实现

ts 复制代码
const any = <T,U>(arr:T[], fn: (value: T, index: number, array: T[]) => U) => arr.filter(fn).length > 0;

使用示例

js 复制代码
any([2,3,4,5],n => n < 3); // true

总结

与all的总结一致。

检查 2 个数字是否大致相等

检查两个数字是否大致相等。

实现思路

实现思路如下:

该函数有3个参数,通过abs方法计算前面2个参数的绝对差值,然后与第三个参数进行比较,判断是否小于第三个参数,第三个参数默认值是0.001。

代码实现

下面我们来看php和js以及ts代码的实现:

php代码实现

php 复制代码
function apprEqual($a,$b,$c = 0.001){
    return abs($a - $b) < $c;
}

使用示例

php 复制代码
apprEqual(10.0, 10.00001); // true
apprEqual(10.0, 10.01); // false

js代码实现

js 复制代码
const apprEqual = (a,b,c = 0.001) => Math.abs(a - b) < c;

ts代码实现

ts 复制代码
const apprEqual = (a: number,b:number,c = 0.001) => Math.abs(a - b) < c;

使用示例

js 复制代码
apprEqual(10.0, 10.00001); // true
apprEqual(10.0, 10.01); // false

总结

与js/ts实现不同点如下:

  1. php的获取绝对值的方法名叫abs,而js/ts则是从Math对象中获取,即Math.abs

平均值

返回两个或多个数字的平均值。

实现思路

实现思路如下:

使用sum函数求和,然后除以长度count即可,参数可以使用展开运算符来组成一个数组,注意需要写一个三元表达式,判断长度是否为0。

代码实现

下面我们来看php和js以及ts代码的实现:

php代码实现

php 复制代码
function average(...$arr){
    $len = count($arr);
    return $len === 0 ? 0 : array_sum($arr) / $len;
}

使用示例

php 复制代码
average(1, 2, 3); // 2

js代码实现

js 复制代码
const average = (...arr) => {
    const len = arr.length;
    return len === 0 ? 0 : arr.reduce((r,i) => r += i,0) / len;
}

ts代码实现

ts 复制代码
const average = (...arr: number[]):number => {
    const len = arr.length;
    return len === 0 ? 0 : arr.reduce((r,i) => r += i,0) / len;
}

使用示例

js 复制代码
average(1, 2, 3); // 2

总结

与js/ts实现不同点如下:

  1. php可以直接使用array_sum方法求数字数组的和,js/ts需要循环自己计算(或者自己实现一个sum方法)。

数值限定

将数值限制在边界值 ab 指定的包含范围内。

实现思路

实现思路如下:

如果该数值在范围内,则返回该数值,否则,使用最小值方法和最大值方法返回范围内最接近的数字。

代码实现

下面我们来看php和js以及ts代码的实现:

php代码实现

php 复制代码
function clampNumber($num,$a,$b){
    return max(min($num,max($a,$b)),min($a,$b));
}

使用示例

php 复制代码
clampNumber(2, 3, 5); // 3 
clampNumber(1, -1, -5); // -1

js代码实现

js 复制代码
const clampNumber = (num,a,b) => {
    const max = Math.max,min = Math.min;
    return max(min(num,max(a,b)),min(a,b));
}

ts代码实现

ts 复制代码
const clampNumber = (num:number,a:number,b:number) => {
    const max = Math.max,min = Math.min;
    return max(min(num,max(a,b)),min(a,b));
}

使用示例

js 复制代码
clampNumber(2, 3, 5); // 3 
clampNumber(1, -1, -5); // -1

总结

与js/ts实现不同点如下:

  1. php的获取最小值和最大值的方法名叫minmax,而js/ts则是从Math对象中获取,即Math.minMath.max

组合函数

返回一个将多个函数组合成单个可调用函数的新函数。

实现思路

实现思路如下:

使用 array_reduce() 执行从右到左的函数组合。该函数接收3个参数,第一个参数为函数列表,第二个参数是一个回调函数用来合并数组中的每一个函数,第三个参数是函数的初始值,即$function($x){ return $x; },默认是一个恒等函数,也就是一个返回其输入参数本身的函数。

代码实现

下面我们来看php和js以及ts代码的实现:

php代码实现

php 复制代码
function compose(...$fns){
    return array_reduce(
        $fns,
        function ($carry,$fn){
            // 使用 use语句导入闭包中的变量$carry,$fn
            return function($x) use ($carry,$fn){
                return $carry($fn($x));
            }
        },
        $function($x){
            return $x;
        }
    )
}

使用示例

php 复制代码
$compose = compose(
  // 加2
  function ($x) {
    return $x + 2;
  },
  // 乘以4
  function ($x) {
    return $x * 4;
  }
);
$compose(3); // 20

js代码实现

js 复制代码
const compose = (...fns) => fns.reduce((f,h) => (...args) => f(h(...args)));

ts代码实现

ts 复制代码
type ComposeFn<T extends any> = (...args: T[]) => T;

const compose = <T,U extends ComposeFn<T>[]>(...fns: U) =>
    fns.reduce(
        (f, h) =>
            (...args: Parameters<ComposeFn<T>>) => f(h(...args))
    );

使用示例

js 复制代码
const add5 = x => x + 5;
const multiply = (x, y) => x * y;
const multiplyAndAdd5 = compose(add5, multiply);
const res = multiplyAndAdd5(5, 2); // 15

总结

与js/ts实现不同点如下:

  1. php需要使用use语句来导入闭包中的变量,而js/ts则不需要。
  2. php使用array_reduce方法来遍历函数数组,并且需要提供一个恒等函数作为第三个参数的初始值,而js/ts直接调用数组的reduce方法来遍历函数数组,并且不需要提供第三个作为初始值的参数。

统计字符串中元音字母的数量

返回所提供字符串中的元音字母数量。

实现思路

实现思路如下:

使用正则表达式来匹配元音字母,元音字母包含a、e、i、o、u等字母。调用php的preg_match_all方法来匹配,然后使用count方法计算返回值的长度,即为元音字母的数量。

代码实现

下面我们来看php和js以及ts代码的实现:

php代码实现

php 复制代码
function countVowels($str){
    preg_match_all('/[aeiou]/i',$str,$matches);
    // $matches为匹配结果
    return count($matches[0]);
}

使用示例

php 复制代码
countVowels('sampleInput'); // 4

js代码实现

js 复制代码
const countVowels = (str) => [...str.matchAll(/[aeiou]/ig)].length;

ts代码实现

ts 复制代码
const countVowels = (str: string) => [...str.matchAll(/[aeiou]/ig)].length;

使用示例

js 复制代码
countVowels('sampleInput'); // 4

总结

与js/ts实现不同点如下:

  1. php使用preg_match_all方法来匹配字符串所有符合条件的字符,而js/ts则使用String.matchAll方法。
  2. php 定义正则表达式和js/ts有所区别,需要把正则表达式当作一个字符串。
  3. js/ts调用matchAll方法时需要提供一个g修饰符,表示用来匹配全局,php则不需要。
  4. js/ts调用matchAll方法返回的是一个迭代器,需要使用展开运算符转换成数组,然后再计算长度。
  5. php使用count方法来获取数组的长度,而js/ts可以直接通过length属性来获取。

柯里化函数

对函数进行柯里化,以便在多次调用中获取参数。

实现思路

实现思路如下:

  1. curry接收一个函数参数,返回执行的累积器$acc
  2. 使用&操作符引用累积器,使用use语句导入函数和累积器。
  3. 使用array_merge方法合并所有参数。
  4. 使用php反射ReflectionFunction获取函数所需参数数量,然后调用getNumberOfRequiredParameters方法获取必需参数的数量。
  5. 如果必需参数数量小于等于外部参数数量,则直接返回函数执行参数结果,否则递归的执行累积器。

代码实现

下面我们来看php和js以及ts代码的实现:

php代码实现

php 复制代码
function curry($fn){
    $acc = function ($arg) use ($fn,&$acc){
        return function (...$args) use($fn,$arg,$acc){
            // 合并参数
            $arg = array_merge($args);
            // 创建一个反射
            $ref = new ReflectionFunction($fn);
            // 通过反射获取必需参数
            $totalArgs = $ref -> getNumberOfRequiredParameters();
            
            if($totalArgs <= count($arg)){
                return $fn(...$arg);
            }
            
            return $acc($arg);
        }
    }
    
    return $acc([]);
}

使用示例

php 复制代码
$curriedAdd = curry(function ($a, $b) { return $a + $b; }); 
$add10 = $curriedAdd(10); 
var_dump($add10(15)); // 25

js代码实现

js 复制代码
const curry = fn => (...args) => args.length >= fn.length ? fn(...args) : (...nArgs) => curry(fn)(...args,...nArgs);

ts代码实现

ts 复制代码
const curry =
  <T, R, F extends (...args: T[]) => R>(fn: F) =>
  (...args: T[]) =>
    args.length >= fn.length
      ? fn(...args)
      : (...nArgs: T[]) => curry(fn as (...args: unknown[]) => unknown)(...args, ...nArgs);

使用示例

js 复制代码
const curriedAdd = curry((a,b) => a + b); 
const add10 = curriedAdd(10); 
const res = add10(15); // 25

总结

与js/ts实现不同点如下:

  1. php中使用了反射相关方法来获取参数,而js/ts则不需要。
  2. php使用array_merge方法来合并参数,而js/ts则不需要。
  3. 两者的判断逻辑也有差异。

ps: 两者的实现都采用了递归的方式,这点需要注意。

取消字符串首字母大写

取消字符串首字母的大写。

实现思路

实现思路如下:

调用lcfirst方法可以直接将字符串大写首字母转换成小写,根据第二个参数$upperRest来决定是否将其余字母转换成大写,使用strtoupper方法即可。

代码实现

下面我们来看php和js以及ts代码的实现:

php代码实现

php 复制代码
function decapitalize($str,$upperRest = false){
    return lcfirst($upperRest ? strtoupper($str) : $str);
}

使用示例

php 复制代码
decapitalize('FooBar'); // 'fooBar'

js代码实现

js 复制代码
const decapitalize = (str, upperRest = false) => str.slice(0,1).toLowerCase() + `${upperRest ? str.slice(1).toUpperCase() : str.slice(1)}`;

ts代码实现

ts 复制代码
const decapitalize = (str: string, upperRest = false) => str.slice(0,1).toLowerCase() + `${upperRest ? str.slice(1).toUpperCase() : str.slice(1)}`;

使用示例

js 复制代码
decapitalize('FooBar'); // 'fooBar'

总结

与js/ts实现不同点如下:

  1. php有方法可以直接将首字母转换成小写,而js/ts则需要通过slice(或其它字符串的截取方法,例如:substr)方法来截取字符串,然后拼接在一起。
  2. php转换成大写的方法是strtoupper,而js/ts则是通过调用String.toUpperCase方法来转换成大写。

深度展开数组

深度展平数组,直接将多维数组转成一维数组。

实现思路

实现思路如下:

使用foreach循环数组,如果数组项是数组(使用is_array方法来判断),则使用递归加array_push和空数组以及展开运算符来合并数组,否则直接使用[]语法来添加数组项(相当于array_push方法)。

代码实现

下面我们来看php和js以及ts代码的实现:

php代码实现

php 复制代码
function deepFlatten($items){
    $res = [];
    foreach($item as $items){
        if(is_array($item)){
            array_push($res,...deepFlatten($item));
        }else{
            $res[] = $item;
        }
    }
    return $res;
}

使用示例

php 复制代码
deepFlatten([1, [2], [[3], 4], 5]); // [1, 2, 3, 4, 5]

js代码实现

js 复制代码
const deepFlatten = (items) => {
  let res = [];
  for(const item of items){
    if(Array.isArray(item) && item.length > 0){
      res.push(...deepFlatten(item))
    }else{
      res.push(item)
    }
  }
  return res;
}

ts代码实现

ts 复制代码
const deepFlatten = <T>(items: T[]) => {
  let res: T[] = [];
  for (const item of items) {
    if (Array.isArray(item) && item.length > 0) {
      res.push(...deepFlatten(item));
    } else {
      res.push(item);
    }
  }
  return res;
};

使用示例

js 复制代码
deepFlatten([1, [2], [[3], 4], 5]); // [1, 2, 3, 4, 5]

总结

与js/ts实现不同点如下:

  1. php使用array_push方法来往数组末尾添加元素,而js/ts则是直接使用push方法。
  2. php可以使用[]语法来代替array_push方法,js/ts没有相关语法。
  3. php使用is_array方法来判断是否是数组,而js/ts则使用Array.isArray方法。
  4. php使用foreach循环遍历数组,js/ts没有foreach循环,但可以使用for循环代替。

最后

感谢大家阅读本文,如果有收获和帮助,希望不吝啬点赞收藏,以上代码段来自网络,并总结到我的代码段网站中。

相关推荐
追逐时光者5 小时前
推荐 12 款开源美观、简单易用的 WPF UI 控件库,让 WPF 应用界面焕然一新!
后端·.net
Jagger_5 小时前
敏捷开发流程-精简版
前端·后端
苏打水com6 小时前
数据库进阶实战:从性能优化到分布式架构的核心突破
数据库·后端
间彧7 小时前
Spring Cloud Gateway与Kong或Nginx等API网关相比有哪些优劣势?
后端
间彧7 小时前
如何基于Spring Cloud Gateway实现灰度发布的具体配置示例?
后端
间彧7 小时前
在实际项目中如何设计一个高可用的Spring Cloud Gateway集群?
后端
间彧7 小时前
如何为Spring Cloud Gateway配置具体的负载均衡策略?
后端
间彧7 小时前
Spring Cloud Gateway详解与应用实战
后端
EnCi Zheng9 小时前
SpringBoot 配置文件完全指南-从入门到精通
java·spring boot·后端
烙印6019 小时前
Spring容器的心脏:深度解析refresh()方法(上)
java·后端·spring