# Function

参考

# array_concat

返回一个由当前数组和其它任何数组或值拼接而成的新数组。

数组

添加版本

0.0.1

语法

array_concat(array, values);

参数

  • array(Array): 需要处理的数组。
  • values(...*): 拼接的数组或值

返回值

(Array): 拼接成的新数组

示例

@langnang/js-func/test/array_concat.tsx (opens new window)

import { array_concat } from "../main";

describe("array_concat", () => {
  it("MDN: 连接两个数组", () => {
    expect(array_concat(['a', 'b', 'c'], [1, 2, 3])).toEqual(['a', 'b', 'c', 1, 2, 3])
  })
  it("MDN: 连接三个数组", () => {
    expect(array_concat([1, 2, 3], [4, 5, 6], [7, 8, 9])).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9])
  })
  it("MDN: 将值连接到数组", () => {
    expect(array_concat(['a', 'b', 'c'], 1, [2, 3])).toEqual(['a', 'b', 'c', 1, 2, 3])
  })
  it("MDN: 合并嵌套数组", () => {
    expect(array_concat([[1]], [2, [3]])).toEqual([[1], 2, [3]])
  })
})

参考

实现

  • Langnang.array_concat
  • Lodash.concat

@langnang/js-func/src/array_concat.ts (opens new window)

import { is_array } from './is_array'
/**
 * @name array_concat
 * @description 返回一个由当前数组和其它任何数组或值拼接而成的新数组。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {...*} values 拼接的数组或值
 * @returns {Array} 拼接成的新数组
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/concat
 * @tutorial https://www.lodashjs.com/docs/lodash.concat
 */
export const array_concat = (array: any[], ...values: any): any[] => {
  let result = [...array];
  for (let i = 0; i <= values.length - 1; i++) {
    if (is_array(values[i])) {
      result = [...result, ...values[i]];
    } else {
      result = [...result, values[i]];
    }
  }
  return result;
};

# array_count

遍历数组,计数统计使用 iteratee 迭代函数处理每个元素后返回结果的出现次数

数组

添加版本

0.0.1

语法

array_count(array, iteratee(element, index, array), this_arg);

参数

  • array(Array): 需要处理的数组。
  • iteratee(element, index, array)(*): 每次迭代调用的函数。
    • element(*): 当前遍历到的元素。
    • index(Number): 当前遍历到的索引。
    • array(Array): 数组本身。
  • this_arg(*): 执行回调时用作 this 的对象。

返回值

(Object): 返回一个组成集合对象。

示例

@langnang/js-func/test/array_count.tsx (opens new window)

import { array_count } from '../main'

describe("array_count", () => {
  it("main", () => { });
  it("MDN", () => { });
  it("Lodash", () => {
    expect(array_count([6.1, 4.2, 6.3], Math.floor)).toEqual({ '4': 1, '6': 2 })

    // The `_.property` iteratee shorthand.
    // expect(array_count(['one', 'two', 'three'], 'length')).toEqual({ '3': 2, '5': 1 })
  });
  it("Underscore", () => {
    expect(array_count([1, 2, 3, 4, 5], function (num: any) {
      return num % 2 == 0 ? 'even' : 'odd';
    })).toEqual({ odd: 3, even: 2 });
  });
})

参考

实现

  • Langnang.array_count
  • Lodash.countBy
  • Underscore.countBy

@langnang/js-func/src/array_count.ts (opens new window)

/**
 * @name array_count
 * @description 遍历数组,计数统计使用 `iteratee` 迭代函数处理每个元素后返回结果的出现次数
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} iteratee(element, index, array) 每次迭代调用的函数。
 * * @param {*} element 当前遍历到的元素。
 * * @param {Number} index 当前遍历到的索引。
 * * @param {Array} array 数组本身。
 * @param {*} this_arg 执行回调时用作 `this` 的对象。
 * @returns {Object} 返回一个组成集合对象。
 * @tutorial https://www.lodashjs.com/docs/lodash.countBy
 * @tutorial https://underscorejs.net/#countBy
 */
export const array_count = (array: any[], iteratee: any = null, this_arg: any = null): any => {
  let result = iteratee ? array.map(iteratee) : [...array];
  return result.reduce((total: object, current_value: any) => {
    total[current_value] = (total[current_value] || 0) + 1;
    return total;
  }, {})
}

# array_duplicate

返回数组中的重复值。

数组

添加版本

0.0.1

语法

array_duplicate(array);

参数

  • array(Array): 需要处理的数组。

返回值

(Array): 由重复值组成的新数组

示例

@langnang/js-func/test/array_duplicate.tsx (opens new window)

import { array_duplicate } from '../main'

describe("array_duplicate", () => {
  it("main", () => {
    expect(array_duplicate([1, 1, 1, 1, 1, 3, 4, 5])).toEqual([1])
  });
  it("MDN", () => { });
  it("Lodash", () => { });
  it("Underscore", () => { });
})

实现

  • Langnang.array_duplicate

@langnang/js-func/src/array_duplicate.ts (opens new window)

/**
 * @name array_duplicate
 * @description 返回数组中的重复值。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @returns {Array} 由重复值组成的新数组
 */

export const array_duplicate = (array: any[]): any[] => [
  ...new Set(
    array.reduce(
      (total, current_value, current_index) =>
        array.indexOf(current_value, current_index + 1) >= 0 ? total.concat(current_value) : total,
      []
    )
  ),
];

# array_every

遍历数组,使用 predicate 断言函数检测数组内的所有元素是否都能通过测试。如果所有元素都通过就返回 true,否则返回 false

数组

TIP

这个方法对于对于空集合返回 true,因为空集合的任何元素都是 true

添加版本

0.0.1

语法

array_every(array, predicate(element, index, array), this_arg);

参数

  • array(Array): 需要处理的数组。
  • predicate(element, index, array)(*): 每次迭代调用的函数。
    • element(*): 当前遍历到的元素。
    • index(Number): 当前遍历到的索引。
    • array(Array): 数组本身。
  • this_arg(*): 执行回调时用作 this 的对象。

返回值

(Boolean): 如果所有元素通过 predicate 断言函数检测后都返回真值,那么就返回 true,否则返回 false

示例

@langnang/js-func/test/array_every.tsx (opens new window)

import { array_every } from "../main";


describe("array_every", () => {
  it("main", () => { });
  it("MDN: 检测所有数组元素的大小", () => {
    function isBigEnough(element: any, index: number, array: any[]) {
      return element >= 10;
    }
    expect(array_every([12, 5, 8, 130, 44], isBigEnough)).toEqual(false);
    expect(array_every([12, 54, 18, 130, 44], isBigEnough)).toEqual(true);
  });
  it("Lodash", () => {
    expect(array_every([true, 1, null, 'yes'], Boolean)).toEqual(false);
    // => false

    var users = [
      { 'user': 'barney', 'age': 36, 'active': false },
      { 'user': 'fred', 'age': 40, 'active': false }
    ];

    // The `_.matches` iteratee shorthand.
    // _.every(users, { 'user': 'barney', 'active': false });
    // => false

    // The `_.matchesProperty` iteratee shorthand.
    // _.every(users, ['active', false]);
    // => true

    // The `_.property` iteratee shorthand.
    // _.every(users, 'active');
    // => false

  });
  it("Underscore", () => {
    expect(array_every([2, 4, 5], function (num: any) { return num % 2 == 0; })).toEqual(false);
  });
})

参考

实现

  • Langnang.array_every
  • Lodash.every
  • Underscore.every

@langnang/js-func/src/array_every.ts (opens new window)

/**
 * @name array_every
 * @description 遍历数组,使用 `predicate` 断言函数检测数组内的所有元素是否都能通过测试。如果所有元素都通过就返回 `true`,否则返回 `false` 。
 * @tip 这个方法对于对于空集合返回 true,因为空集合的任何元素都是 `true` 。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} predicate(element, index, array) 每次迭代调用的函数。
 * * @param {*} element 当前遍历到的元素。
 * * @param {Number} index 当前遍历到的索引。
 * * @param {Array} array 数组本身。
 * @param {*} this_arg 执行回调时用作 `this` 的对象。
 * @returns {Boolean} 如果所有元素通过 `predicate` 断言函数检测后都返回真值,那么就返回 `true`,否则返回 `false` 。
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/every
 * @tutorial https://www.lodashjs.com/docs/lodash.every
 * @tutorial https://underscorejs.net/#every
 */
export const array_every = (array: any[], predicate: any, this_arg: any = null) => {
  for (let key in array) {
    if (!predicate(array[key], key, array)) {
      return false;
    }
  }
  return true;
};

# array_every_equal

检测数组所有元素是否全等

数组

添加版本

0.0.1

语法

array_every_equal(array);

参数

  • array(Array): 需要检测的数组

返回值

(Boolean): 检测结果

示例

@langnang/js-func/test/array_every_equal.tsx (opens new window)

import { array_every_equal } from '../main'

describe("array_every_equal", () => {
  it("main", () => {
    expect(array_every_equal([1, 1, 1, 1, 1])).toEqual(true)
  });
})

实现

  • Langnang.array_every_equal

@langnang/js-func/src/array_every_equal.ts (opens new window)

import { array_every } from "./array_every";

/**
 * @name array_every_equal
 * @description 检测数组所有元素是否全等
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要检测的数组
 * @returns {Boolean} 检测结果
 */
export const array_every_equal = (array: any[]) => array_every(array, (val: any) => val === array[0])

# array_fill

用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。

数组

添加版本

0.0.1

语法

array_fill(array, value, [start = 0], [end = array.length]);

参数

  • array(Array): 需要处理的数组。
  • value(*): 用来填充数组元素的值。
  • [start = 0](Number): 起始索引,默认值为 0。
  • [end = array.length](Number): 终止索引,默认值为 array.length

返回值

(Array): 返回填充修改后的数组。

示例

@langnang/js-func/test/array_fill.tsx (opens new window)

import { array_fill } from "../main";

describe("array_fill", () => {
  it("MDN", () => {
    expect(array_fill([1, 2, 3], 4)).toEqual([4, 4, 4]);
    expect(array_fill([1, 2, 3], 4, 1)).toEqual([1, 4, 4]);
    expect(array_fill([1, 2, 3], 4, 1, 2)).toEqual([1, 4, 3]);
    expect(array_fill([1, 2, 3], 4, 1, 1)).toEqual([1, 2, 3]);
    expect(array_fill([1, 2, 3], 4, 3, 3)).toEqual([1, 2, 3]);
    // expect(array_fill([1, 2, 3], 4, -3, -2)).toEqual([4, 2, 3]);
    expect(array_fill([1, 2, 3], 4, NaN, NaN)).toEqual([1, 2, 3]);
    expect(array_fill([1, 2, 3], 4, 3, 5)).toEqual([1, 2, 3]);
  })

  it("Lodash", () => {
    expect(array_fill([1, 2, 3], "a")).toEqual(["a", "a", "a"]);
    expect(array_fill(Array(3), 2)).toEqual([2, 2, 2]);
    expect(array_fill([4, 6, 8, 10], "*", 1, 3)).toEqual([4, '*', '*', 10]);
  })
})

参考

实现

  • Langnang.array_fill
  • Lodash.fill

@langnang/js-func/src/array_fill.ts (opens new window)

/**
 * @name array_fill
 * @description 用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} value 用来填充数组元素的值。
 * @param {Number} [start = 0] 起始索引,默认值为 0。
 * @param {Number} [end = array.length] 终止索引,默认值为 `array.length`。
 * @returns {Array} 返回填充修改后的数组。
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/fill
 * @tutorial https://www.lodashjs.com/docs/lodash.fill
 */
export const array_fill = (array: any[], value: any, start: number = 0, end: number = array.length): any[] => {
  const result = [...array];
  end = end < array.length ? end : array.length;
  for (let i = start; i < end; i++) {
    result[i] = value;
  }
  return result;
};

# array_filter

过滤数组,并将符合条件(返回 true)的数组元素放进一个新数组中并返回。

数组

添加版本

0.0.1

语法

array_filter(array, predicate(element, index, array), this_arg);

参数

  • array(Array): 需要处理的数组。
  • predicate(element, index, array)(*): 每次迭代调用的函数。
    • element(*): 当前遍历到的元素。
    • index(Number): 当前遍历到的索引。
    • array(Array): 数组本身。
  • this_arg(*): 执行回调时用作 this 的对象。

返回值

(Array): 返回一个新的过滤后的数组。

示例

@langnang/js-func/test/array_filter.tsx (opens new window)

import { array_filter } from '../main'

describe("array_filter", () => {
  it("main", () => { });
  it("MDN: 筛选排除所有较小的值", () => {
    expect(array_filter([12, 5, 8, 130, 44], (value: any) => value > 10)).toEqual([12, 130, 44]);
  });
  it("MDN: 找出数组中所有的素数", () => {
    function isPrime(num: any) {
      for (let i = 2; num > i; i++) {
        if (num % i === 0) {
          return false;
        }
      }
      return num > 1;
    }
    expect(array_filter([-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], isPrime)).toEqual([2, 3, 5, 7, 11, 13]);
  });
  it("MDN: 过滤 JSON 中的无效条目", () => {
    const array = [
      { id: 15 },
      { id: -1 },
      { id: 0 },
      { id: 3 },
      { id: 12.2 },
      {},
      { id: null },
      { id: NaN },
      { id: 'undefined' },
    ];
    let invalidEntries = 0;
    function filterByID(item: any) {
      if (Number.isFinite(item.id) && item.id !== 0) {
        return true;
      }
      invalidEntries++;
      return false;
    }
    expect(array_filter(array, filterByID)).toEqual([{ id: 15 }, { id: -1 }, { id: 3 }, { id: 12.2 }]);
  });
  it("MDN: 在数组中搜索", () => {
    const fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];
    function filterItems(array: any[], query: string) {
      return array_filter(array, (el: any) => el.toLowerCase().includes(query.toLowerCase()));
    }
    expect(filterItems(fruits, 'ap')).toEqual(['apple', 'grapes']);
    expect(filterItems(fruits, 'an')).toEqual(['banana', 'mango', 'orange']);
  });
  it("Lodash", () => {
    var users = [
      { 'user': 'barney', 'age': 36, 'active': true },
      { 'user': 'fred', 'age': 40, 'active': false }
    ];
    expect(array_filter(users, function (o: any) { return !o.active; })).toEqual([{ 'user': 'fred', 'age': 40, 'active': false }])
    // => objects for ['fred']

    // The `_.matches` iteratee shorthand.
    // expect(array_filter(users, { 'age': 36, 'active': true })).toEqual([{ 'user': 'barney', 'age': 36, 'active': true }])
    // => objects for ['barney']

    // The `_.matchesProperty` iteratee shorthand.
    // array_filter(users, ['active', false]);
    // => objects for ['fred']

    // The `_.property` iteratee shorthand.
    // array_filter(users, 'active');
    // => objects for ['barney']
  });
  it("Underscore", () => {
    expect(array_filter([1, 2, 3, 4, 5, 6], function (num: any) { return num % 2 == 0; })).toEqual([2, 4, 6])
  });
})

参考

实现

  • Langnang.array_filter
  • Lodash.filter
  • Underscore.filter

@langnang/js-func/src/array_filter.ts (opens new window)

import { array_push } from "./array_push";
/**
 * @name array_filter
 * @description 过滤数组,并将符合条件(返回 `true`)的数组元素放进一个新数组中并返回。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} predicate(element, index, array) 每次迭代调用的函数。
 * * @param {*} element 当前遍历到的元素。
 * * @param {Number} index 当前遍历到的索引。
 * * @param {Array} array 数组本身。
 * @param {*} this_arg 执行回调时用作 `this` 的对象。
 * @returns {Array} 返回一个新的过滤后的数组。
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
 * @tutorial https://www.lodashjs.com/docs/lodash.filter
 * @tutorial https://underscorejs.net/#filter
 */
export const array_filter = (array: any[], predicate: any, this_arg: any = null): any[] => {
  let result: any[] = [];
  for (let key in array) {
    if (predicate(array[key], key, array)) {
      array_push(result, array[key]);
    }
  }
  return result;
};

# array_filter_falsy

过滤数组中的虚假值

数组

添加版本

0.0.1

语法

array_filter_falsy(array);

参数

  • array(Array): 需要处理的数组。

返回值

(Array): 返回一个新的过滤后的数组。

示例

@langnang/js-func/test/array_filter_falsy.tsx (opens new window)

import { array_filter_falsy } from '../main'

describe("array_filter_falsy", () => {
  it("main", () => {
    expect(array_filter_falsy([0, 1, '', undefined, null, NaN])).toEqual([1])
  });
  it("MDN", () => { });
  it("Lodash", () => { });
  it("Underscore", () => { });
})

实现

  • Langnang.array_filter_falsy

@langnang/js-func/src/array_filter_falsy.ts (opens new window)

import { array_filter } from "./array_filter";
/**
 * @name array_filter_falsy
 * @description 过滤数组中的虚假值
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @returns {Array} 返回一个新的过滤后的数组。
 */
export const array_filter_falsy = (array: any[]): any[] => array_filter(array, Boolean);

# array_find

遍历数组,返回第一个通过 predicate 迭代函数检测的元素值,如果没有元素通过检测则返回 undefined

数组

添加版本

0.0.1

语法

array_find(array, predicate(element, index, array), [form_index = 0], this_arg);

参数

  • array(Array): 需要处理的数组。
  • predicate(element, index, array)(*): 每次迭代调用的函数。
    • element(*): 当前遍历到的元素。
    • index(Number): 当前遍历到的索引。
    • array(Array): 数组本身。
  • [form_index = 0](Number): 开始搜索的索引位置。
  • this_arg(*): 执行回调时用作 this 的对象。

返回值

(*): 数组中第一个满足所提供测试函数的元素的值,否则返回 undefined。

示例

@langnang/js-func/test/array_find.tsx (opens new window)

import { array_find } from "../main";

describe("array_find", () => {
  it("MDN: 用对象的属性查找数组里的对象", () => {
    const inventory = [
      { name: "apples", quantity: 2 },
      { name: "bananas", quantity: 0 },
      { name: "cherries", quantity: 5 },
    ];

    function isCherries(fruit: any) {
      return fruit.name === "cherries";
    }
    expect(array_find(inventory, isCherries)).toEqual({ name: "cherries", quantity: 5, });
  });
  it("MDN: 使用箭头函数和解构赋值", () => {
    const inventory = [
      { name: "apples", quantity: 2 },
      { name: "bananas", quantity: 0 },
      { name: "cherries", quantity: 5 },
    ];
    expect(array_find(inventory, ({ name }: any) => name === "cherries")).toEqual({ name: "cherries", quantity: 5, });
  });
  it("MDN: 寻找数组中的第一个质数", () => {
    function isPrime(element: any, index: number, array: any[]) {
      let start = 2;
      while (start <= Math.sqrt(element)) {
        if (element % start++ < 1) {
          return false;
        }
      }
      return element > 1;
    }
    expect(array_find([4, 6, 8, 12], isPrime)).toEqual(undefined);
    expect(array_find([4, 5, 8, 12], isPrime)).toEqual(5);

  });
  it("Lodash", () => {
    var users = [
      { 'user': 'barney', 'age': 36, 'active': true },
      { 'user': 'fred', 'age': 40, 'active': false },
      { 'user': 'pebbles', 'age': 1, 'active': true }
    ];

    expect(array_find(users, function (o: any) { return o.age < 40; })).toEqual({ 'user': 'barney', 'age': 36, 'active': true });
    // => object for 'barney'

    // The `_.matches` iteratee shorthand.
    // _.find(users, { 'age': 1, 'active': true });
    // => object for 'pebbles'

    // The `_.matchesProperty` iteratee shorthand.
    // _.find(users, ['active', false]);
    // => object for 'fred'

    // The `_.property` iteratee shorthand.
    // _.find(users, 'active');
    // => object for 'barney'
  });
  it("Underscore", () => {
    expect(array_find([1, 2, 3, 4, 5, 6], function (num: any) { return num % 2 == 0; })).toEqual(2);
  });
});

参考

实现

  • Langnang.array_find
  • Lodash.find
  • Underscore.find

@langnang/js-func/src/array_find.ts (opens new window)

/**
 * @name array_find
 * @description 遍历数组,返回第一个通过 `predicate` 迭代函数检测的元素值,如果没有元素通过检测则返回 `undefined`。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} predicate(element, index, array) 每次迭代调用的函数。
 * * @param {*} element 当前遍历到的元素。
 * * @param {Number} index 当前遍历到的索引。
 * * @param {Array} array 数组本身。
 * @param {Number} [form_index = 0] 开始搜索的索引位置。
 * @param {*} this_arg 执行回调时用作 `this` 的对象。
 * @returns {*} 数组中第一个满足所提供测试函数的元素的值,否则返回 undefined。
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/find
 * @tutorial https://www.lodashjs.com/docs/lodash.find
 * @tutorial https://underscorejs.net/#find
 */
export const array_find = (array: any[], predicate: any, form_index: number = 0, this_arg: any = null) => {
  form_index = (form_index < 0 || form_index > array.length) ? 0 : form_index;
  for (let i = form_index; i < array.length; i++) {
    if (predicate(array[i], i, array)) {
      return array[i];
    }
  }
  return undefined;
};

# array_find_index

遍历数组,返回第一个通过 predicate 迭代函数检测的元素索引,如果没有元素通过检测则返回 -1

数组

添加版本

0.0.1

语法

array_find_index(array, predicate(element, index, array), form_index, this_arg);

参数

  • array(Array): 需要处理的数组。
  • predicate(element, index, array)(*): 每次迭代调用的函数。
    • element(*): 当前遍历到的元素。
    • index(Number): 当前遍历到的索引。
    • array(Array): 数组本身。
  • form_index(Number): 开始搜索的索引位置。
  • this_arg(*): 执行回调时用作 this 的对象。

返回值

(*): 数组中第一个满足所提供测试函数的元素的值,否则返回 -1

示例

@langnang/js-func/test/array_find_index.tsx (opens new window)

import { array_find_index } from '../main'

describe("array_find_index", () => {
  it("main", () => { });
  it("MDN: 查找数组中首个质数元素的索引", () => {
    function isPrime(element: any, index: number, array: any[]) {
      var start = 2;
      while (start <= Math.sqrt(element)) {
        if (element % start++ < 1) {
          return false;
        }
      }
      return element > 1;
    }
    expect(array_find_index([4, 6, 8, 12], isPrime)).toEqual(-1);
    expect(array_find_index([4, 6, 7, 12], isPrime)).toEqual(2);
  });
  it("Lodash", () => {
    var users = [
      { 'user': 'barney', 'active': false },
      { 'user': 'fred', 'active': false },
      { 'user': 'pebbles', 'active': true }
    ];

    expect(array_find_index(users, function (o: any) { return o.user == 'barney'; })).toEqual(0);
    // => 0

    // The `_.matches` iteratee shorthand.
    // _.findIndex(users, { 'user': 'fred', 'active': false });
    // => 1

    // The `_.matchesProperty` iteratee shorthand.
    // _.findIndex(users, ['active', false]);
    // => 0

    // The `_.property` iteratee shorthand.
    // _.findIndex(users, 'active');
    // => 2
  });
  it("Underscore", () => { });
})

参考

实现

  • Langnang.array_find_index
  • Lodash.findIndex
  • Underscore.findIndex

@langnang/js-func/src/array_find_index.ts (opens new window)

/**
 * @name array_find_index
 * @description 遍历数组,返回第一个通过 `predicate` 迭代函数检测的元素索引,如果没有元素通过检测则返回 `-1`。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} predicate(element, index, array) 每次迭代调用的函数。
 * * @param {*} element 当前遍历到的元素。
 * * @param {Number} index 当前遍历到的索引。
 * * @param {Array} array 数组本身。
 * @param {Number} form_index 开始搜索的索引位置。
 * @param {*} this_arg 执行回调时用作 `this` 的对象。
 * @returns {*} 数组中第一个满足所提供测试函数的元素的值,否则返回 `-1`
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex
 * @tutorial https://www.lodashjs.com/docs/lodash.findIndex
 * @tutorial https://underscorejs.net/#findIndex
 */
export const array_find_index = (array: any[], predicate: any, form_index: number = 0, this_arg: any = null) => {
  form_index = (form_index < 0 || form_index > array.length) ? 0 : form_index;
  for (let i = form_index; i < array.length; i++) {
    if (predicate(array[i], i, array)) {
      return i;
    }
  }
  return -1;
};

# array_flat

按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。

数组

添加版本

0.0.1

语法

array_flat(array, [depth = 1]);

参数

  • array(Array): 需要处理的数组
  • [depth = 1](Number): 指定要提取嵌套数组的结构深度,默认值为 1。0:不提取,-1:提取所有深度。

返回值

(Array): 一个包含将数组与子数组中所有元素的新数组。

示例

@langnang/js-func/test/array_flat.tsx (opens new window)

import { array_flat } from '../main'

describe("array_flat", () => {
  it("main", () => { });
  it("MDN: 扁平化嵌套数组", () => {
    expect(array_flat([1, 2, [3, 4]])).toEqual([1, 2, 3, 4])

    expect(array_flat([1, 2, [3, 4, [5, 6]]])).toEqual([1, 2, 3, 4, [5, 6]]);

    expect(array_flat([1, 2, [3, 4, [5, 6]]], 2)).toEqual([1, 2, 3, 4, 5, 6]);

    //使用 -1,可展开任意深度的嵌套数组
    expect(array_flat([1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]], -1)).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
  });
  it("MDN: 扁平化与数组空项", () => {
    expect(array_flat([1, 2, , 4, 5])).toEqual([1, 2, 4, 5]);
  });
  it("Lodash: flatten", () => {
    expect(array_flat([1, [2, [3, [4]], 5]])).toEqual([1, 2, [3, [4]], 5])
  });
  it("Lodash: flattenDeep", () => {
    expect(array_flat([1, [2, [3, [4]], 5]], -1)).toEqual([1, 2, 3, 4, 5])
  });
  it("Lodash: flattenDepth", () => {
    expect(array_flat([1, [2, [3, [4]], 5]], 1)).toEqual([1, 2, [3, [4]], 5])

    expect(array_flat([1, [2, [3, [4]], 5]], 2)).toEqual([1, 2, 3, [4], 5])

  });
  it("Underscore", () => { });
})

参考

实现

  • Langnang.array_flat
  • Lodash.flatten
  • Lodash.flattenDeep
  • Lodash.flattenDepth
  • Underscore.flatten

@langnang/js-func/src/array_flat.ts (opens new window)

import { is_array } from "./is_array";
/**
 * @name array_flat
 * @description 按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组
 * @param {Number} [depth = 1] 指定要提取嵌套数组的结构深度,默认值为 1。0:不提取,-1:提取所有深度。
 * @returns {Array} 一个包含将数组与子数组中所有元素的新数组。
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
 * @tutorial https://www.lodashjs.com/docs/lodash.flatten
 * @tutorial https://www.lodashjs.com/docs/lodash.flattenDeep
 * @tutorial https://www.lodashjs.com/docs/lodash.flattenDepth
 * @tutorial https://underscorejs.net/#flatten
 */

export const array_flat = (array: any[], depth: number = 1): any[] => {
  if (depth >= 1) {
    return array.reduce(
      (a, v) => a.concat(is_array(v) ? array_flat(v, depth - 1) : v),
      []
    );
  }
  if (depth === 0) {
    return array;
  }
  if (depth === -1) {
    return array.reduce((a, v) => a.concat(is_array(v) ? array_flat(v, -1) : v), []);
  }
};

# array_foreach

遍历数组,调用 iteratee 遍历数组中的每个元素。如果迭代函数(iteratee)显式的返回 false ,迭代会提前退出。

数组

添加版本

0.0.1

语法

array_foreach(array, iteratee(element, index, array), this_arg);

参数

  • array(Array): 需要处理的数组。
  • iteratee(element, index, array)(*): 每次迭代调用的函数。
    • element(*): 当前遍历到的元素。
    • index(Number): 当前遍历到的索引。
    • array(Array): 数组本身。
  • this_arg(*): 执行回调时用作 this 的对象。

返回值

(*): 返回数组执行遍历的次数,一般为数组的长度。

示例

@langnang/js-func/test/array_foreach.tsx (opens new window)

import { array_foreach } from '../main'

describe("array_foreach", () => {
  it("main", () => {
    expect(array_foreach([1, 2, 3, 4, 5], (value: any) => value < 4)).toEqual(4)
  });
  it("MDN", () => { });
  it("Lodash", () => { });
  it("Underscore", () => { });
})

参考

实现

  • Langnang.array_foreach
  • Lodash.forEach

@langnang/js-func/src/array_foreach.ts (opens new window)

/**
 * @name array_foreach
 * @description 遍历数组,调用 `iteratee` 遍历数组中的每个元素。如果迭代函数(iteratee)显式的返回 false ,迭代会提前退出。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} iteratee(element, index, array) 每次迭代调用的函数。
 * * @param {*} element 当前遍历到的元素。
 * * @param {Number} index 当前遍历到的索引。
 * * @param {Array} array 数组本身。
 * @param {*} this_arg 执行回调时用作 `this` 的对象。
 * @returns {*} 返回数组执行遍历的次数,一般为数组的长度。
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
 * @tutorial https://www.lodashjs.com/docs/lodash.forEach
 */
export const array_foreach = (array: any[], iteratee: any, this_arg: any = null) => {
  let len: number = 0;
  while (len < array.length) {
    const truth = iteratee(array[len], len, array);

    len++;

    if (!truth) break;
  }
  return len;
};

# array_head

获取数组的前 n 个元素。

数组

添加版本

0.0.1

语法

array_head(array, [n = 1]);

参数

  • array(Array): 需要处理的数组。
  • [n = 1](Number): 获取的元素个数

返回值

(Array):

示例

@langnang/js-func/test/array_head.tsx (opens new window)

import { array_head } from '../main'

describe("array_head", () => {
  it("main", () => {
    expect(array_head([1, 2, 3], -1)).toEqual(1);
    expect(array_head([1, 2, 3], 0)).toEqual(1);
    expect(array_head([1, 2, 3], 1)).toEqual(1);
    expect(array_head([1, 2, 3], 2)).toEqual([1, 2]);
    expect(array_head([1, 2, 3], 3)).toEqual([1, 2, 3]);
  });
  it("MDN", () => { });
  it("Lodash", () => {
    expect(array_head([1, 2, 3])).toEqual(1);

    expect(array_head([])).toEqual(undefined);
  });
  it("Underscore", () => {
    expect(array_head([5, 4, 3, 2, 1])).toEqual(5);
  });
})

参考

实现

  • Langnang.array_head
  • Lodash.head

@langnang/js-func/src/array_head.ts (opens new window)

/**
 * @name array_head
 * @description 获取数组的前 `n` 个元素。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {Number} [n = 1] 获取的元素个数
 * @returns {Array}
 * @tutorial https://www.lodashjs.com/docs/lodash.head
 */
import { array_slice } from "./array_slice";
export const array_head = (array: any[], n: number = 1) => {
  if (n <= 1) return array[0];
  if (n >= array.length) return [...array];
  return array_slice(array, 0, n);
};

export const array_head_by_for = (array: any[], n: number = 1) => {
  if (n <= 1) return array[0];
  if (n >= array.length) return [...array];
  let result = [];
  for (let i = 0; i <= n - 1; i++) {
    result[i] = array[i];
  }
  return result;
}

export const array_head_by_proto = (array: any[], n: number = 1) => {
  if (n <= 1) return array[0];
  if (n >= array.length) return [...array];
  return array.slice(0, n);
}

# array_includes

判断数组是否包含一个指定的值,如果包含则返回 true,否则返回 false。

数组

添加版本

0.0.1

语法

array_includes(array, value, [from_index = 0]);

参数

  • array(Array): 需要处理的数组。
  • value(*): 需要查找的元素值。
  • [from_index = 0](Number): 起始索引,默认值为 0。

返回值

(Boolean): 检测结果

示例

@langnang/js-func/test/array_includes.tsx (opens new window)

import { array_includes } from '../main'

describe("array_includes", () => {
  it("main", () => { });
  it("MDN", () => {
    expect(array_includes([1, 2, 3], 2)).toEqual(true);

    expect(array_includes([1, 2, 3], 4)).toEqual(false);

    expect(array_includes([1, 2, 3], 3, 3)).toEqual(false);

    expect(array_includes([1, 2, 3], 3, -1)).toEqual(true);

    // expect(array_includes([1, 2, NaN], NaN)).toEqual(true);
  });
  it("MDN: fromIndex 大于等于数组长度", () => {
    var arr = ['a', 'b', 'c'];

    expect(array_includes(arr, 'c', 3)).toEqual(false);

    expect(array_includes(arr, 'c', 100)).toEqual(false);
  });
  it("MDN: 计算出的索引小于 0", () => {
    var arr = ['a', 'b', 'c'];

    expect(array_includes(arr, 'a', -100)).toEqual(true);
    expect(array_includes(arr, 'b', -100)).toEqual(true);
    expect(array_includes(arr, 'c', -100)).toEqual(true);
    expect(array_includes(arr, 'a', -2)).toEqual(false);
  });
  it("Lodash", () => {
    expect(array_includes([1, 2, 3], 1)).toEqual(true);

    expect(array_includes([1, 2, 3], 1, 2)).toEqual(false);

    // _.includes({ 'user': 'fred', 'age': 40 }, 'fred');
    // => true

    // _.includes('pebbles', 'eb');
    // => true
  });
  it("Underscore", () => {
    expect(array_includes([1, 2, 3], 3)).toEqual(true);
  });
})

参考

实现

  • Langnang.array_includes
  • Lodash.includes
  • Underscore.contains

@langnang/js-func/src/array_includes.ts (opens new window)

import { array_index } from "./array_index";
/**
 * @name array_includes
 * @description 判断数组是否包含一个指定的值,如果包含则返回 true,否则返回 false。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} value 需要查找的元素值。
 * @param {Number} [from_index = 0] 起始索引,默认值为 0。
 * @returns {Boolean} 检测结果
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/includes
 * @tutorial https://www.lodashjs.com/docs/lodash.includes
 * @tutorial https://underscorejs.net/#contains
 */
export const array_includes = (array: any[], value: any, from_index: number = 0): boolean => {
  if (from_index >= array.length) return false;

  from_index = from_index < 0 ? array.length + from_index : from_index;

  return array_index(array, value, from_index) > -1;

}

# array_index

数组中可以找到给定元素的第一个索引,如果不存在,则返回 -1。

数组

添加版本

0.0.1

语法

array_index(array, value, [from_index = 0]);

参数

  • array(Array): 需要处理的数组。
  • value(*): 要查找的元素。
  • [from_index = 0](Number): 起始索引,默认值为 0。

返回值

首个被找到的元素在数组中的索引位置;: 若没有找到则返回 -1。

示例

@langnang/js-func/test/array_index.tsx (opens new window)

import { array_index } from '../main'

describe("array_index", () => {
  it("main", () => { });
  it("MDN: 使用 indexOf()", () => {
    const array = [2, 9, 9];
    expect(array_index(array, 2)).toEqual(0);
    expect(array_index(array, 7)).toEqual(-1);
    expect(array_index(array, 9, 2)).toEqual(2);
    expect(array_index(array, 2, -1)).toEqual(-1);
    expect(array_index(array, 2, -3)).toEqual(0);
  });
  it("MDN: 找出指定元素出现的所有位置", () => {
    const indices: any[] = [];
    const array: any[] = ['a', 'b', 'a', 'c', 'a', 'd'];
    const element: any = 'a';
    let idx: number = array_index(array, element);
    while (idx !== -1) {
      indices.push(idx);
      idx = array_index(array, element, idx + 1);
    }
    expect(indices).toEqual([0, 2, 4]);
  });
  it("MDN: 判断一个元素是否在数组里,不在则更新数组", () => {
    function updateVegetablesCollection(veggies: any[], veggie: any) {
      if (array_index(veggies, veggie) === -1) {
        veggies.push(veggie);
        return `New veggies collection is: ${veggies}`;
      } else {
        return `${veggie} already exists in the veggies collection.`;
      }
    }
    const veggies = ['potato', 'tomato', 'chillies', 'green-pepper'];

    expect(updateVegetablesCollection(veggies, 'spinach')).toEqual('New veggies collection is: potato,tomato,chillies,green-pepper,spinach');
    expect(updateVegetablesCollection(veggies, 'spinach')).toEqual('spinach already exists in the veggies collection.');
    updateVegetablesCollection(veggies, 'spinach');
  });
  it("Lodash", () => {
    expect(array_index([1, 2, 1, 2], 2)).toEqual(1);

    // Search from the `fromIndex`.
    expect(array_index([1, 2, 1, 2], 2, 2)).toEqual(3);
  });
  it("Underscore", () => {
    expect(array_index([1, 2, 3], 2)).toEqual(1);
  });
})

参考

实现

  • Langnang.array_index
  • Lodash.indexOf
  • Underscore.indexOf

@langnang/js-func/src/array_index.ts (opens new window)

import { _from_index } from "./_form_index";
/**
 * @name array_index
 * @description 数组中可以找到给定元素的第一个索引,如果不存在,则返回 -1。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} value 要查找的元素。
 * @param {Number} [from_index = 0] 起始索引,默认值为 0。
 * @returns 首个被找到的元素在数组中的索引位置; 若没有找到则返回 -1。
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
 * @tutorial https://www.lodashjs.com/docs/lodash.indexOf
 * @tutorial https://underscorejs.net/#indexOf
 */
export const array_index = (array: any[], value: any, from_index: number = 0) => {
  from_index = _from_index(array.length, from_index);

  for (let i = from_index; i <= array.length - 1; i++) {
    if (array[i] === value) {
      return i;
    }
  }
  return -1;
};

# array_join

将数组中的所有元素转换为由 separator 分隔的字符串。

数组

添加版本

0.0.1

语法

array_join(array, [separator = ","]);

参数

  • array(Array): 需要处理的数组。
  • [separator = ","](String): 分隔元素。

返回值

(String): 所有数组元素连接的字符串。

示例

@langnang/js-func/test/array_join.tsx (opens new window)

import { array_join } from '../main'

describe("array_join", () => {
  it("main", () => { });
  it("MDN: 使用四种不同的分隔符连接数组元素", () => {
    var array = ['Wind', 'Rain', 'Fire'];

    expect(array_join(array)).toEqual("Wind,Rain,Fire");
    expect(array_join(array, ', ')).toEqual("Wind, Rain, Fire");
    expect(array_join(array, ' + ')).toEqual("Wind + Rain + Fire");
    expect(array_join(array, '')).toEqual("WindRainFire");
  });
  it("Lodash", () => {
    expect(array_join(['a', 'b', 'c'], '~')).toEqual('a~b~c');
  });
  it("Underscore", () => { });
})

参考

实现

  • Langnang.array_join
  • Lodash.join

@langnang/js-func/src/array_join.ts (opens new window)

/**
 * @name array_join
 * @description 将数组中的所有元素转换为由 `separator` 分隔的字符串。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {String} [separator = ","] 分隔元素。
 * @returns {String} 所有数组元素连接的字符串。
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/join
 * @tutorial https://www.lodashjs.com/docs/lodash.join
 */
export const array_join = (array: any[], separator: string = ",") => {
  let result: string = "";
  for (let i: number = 0; i <= array.length - 1; i++) {
    result += array[i];
    if (i < array.length - 1) {
      result += separator;
    }
  }
  return result;
};

# array_keys

返回一个包含数组中每个索引键的数组。

数组

添加版本

0.0.1

语法

array_keys(array);

参数

  • array(Array): 需要处理的数组。

返回值

一个新的数组对象。:

示例

@langnang/js-func/test/array_keys.tsx (opens new window)

import { array_keys } from '../main'

describe("array_keys", () => {
  it("main", () => { });
  it("MDN", () => {
    expect(array_keys(["a", , "c"])).toEqual([0, 1, 2]);
  });
  it("Lodash", () => { });
  it("Underscore", () => { });
})

参考

实现

  • Langnang.array_keys

@langnang/js-func/src/array_keys.ts (opens new window)

import { array_push } from "./array_push";
/**
 * @name array_keys
 * @description 返回一个包含数组中每个索引键的数组。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @returns 一个新的数组对象。
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/keys
 */
export const array_keys = (array: any[]) => {
  let result: any[] = [];
  for (let i: number = 0; i < array.length; i++) {
    array_push(result, i);
  }
  return result;
};

# array_map

遍历数组,根据 iteratee(迭代函数)遍历所有元素返回的结果所组成新的数组。

数组

添加版本

0.0.1

语法

array_map(array, iteratee(element, index, array), this_arg);

参数

  • array(Array): 需要处理的数组。
  • iteratee(element, index, array)(*): 每次迭代调用的函数。
    • element(*): 当前遍历到的元素。
    • index(Number): 当前遍历到的索引。
    • array(Array): 数组本身。
  • this_arg(*): 执行回调时用作 this 的对象。

返回值

(Array): 根据 iteratee(迭代函数)遍历所有元素返回的结果所组成新的数组。

示例

@langnang/js-func/test/array_map.tsx (opens new window)

import { array_map } from '../main'

describe("array_map", () => {
  it("main", () => {

  });
  it("MDN: 求数组中每个元素的平方根", () => {
    const numbers = [1, 4, 9];

    expect(array_map(numbers, (num: any) => Math.sqrt(num))).toEqual([1, 2, 3]);

  });
  it("MDN: 使用 map 重新格式化数组中的对象", () => {
    const kvArray = [
      { key: 1, value: 10 },
      { key: 2, value: 20 },
      { key: 3, value: 30 },
    ];

    expect(array_map(kvArray, ({ key, value }: any) => ({ [key]: value }))).toEqual([{ 1: 10 }, { 2: 20 }, { 3: 30 }])

  });
  it("MDN: 使用一个包含一个参数的函数来映射一个数字数组", () => {
    const numbers = [1, 4, 9];

    expect(array_map(numbers, (num: any) => num * 2)).toEqual([2, 8, 18])

  });
  it("MDN: 映射包含 undefined 的数组", () => {
    const numbers = [1, 2, 3, 4];

    expect(array_map(numbers, (num: any, index: any) => {
      if (index < 3) {
        return num;
      }
    })).toEqual([1, 2, 3, undefined])

  });
  it("Lodash", () => {
    function square(n: number) {
      return n * n;
    }

    expect(array_map([4, 8], square)).toEqual([16, 64]);

    // array_map({ 'a': 4, 'b': 8 }, square);
    // => [16, 64] (iteration order is not guaranteed)

    var users = [
      { 'user': 'barney' },
      { 'user': 'fred' }
    ];

    // The `_.property` iteratee shorthand.
    // array_map(users, 'user');
    // => ['barney', 'fred']

  });
  it("Underscore", () => {
    expect(array_map([1, 2, 3], function (num: any) { return num * 3; })).toEqual([3, 6, 9]);

    // expect(array_map({ one: 1, two: 2, three: 3 }, function (num, key) { return num * 3; })).toEqual([3, 6, 9]);

    expect(array_map([[1, 2], [3, 4]], (e: any) => e[0])).toEqual([1, 3]);

  });
})

参考

实现

  • Langnang.array_map
  • Lodash.map
  • Underscore.map

@langnang/js-func/src/array_map.ts (opens new window)

import { array_push } from "./array_push";
/**
 * @name array_map
 * @description 遍历数组,根据 `iteratee`(迭代函数)遍历所有元素返回的结果所组成新的数组。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} iteratee(element, index, array) 每次迭代调用的函数。
 * * @param {*} element 当前遍历到的元素。
 * * @param {Number} index 当前遍历到的索引。
 * * @param {Array} array 数组本身。
 * @param {*} this_arg 执行回调时用作 `this` 的对象。
 * @returns {Array} 根据 `iteratee`(迭代函数)遍历所有元素返回的结果所组成新的数组。
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map
 * @tutorial https://www.lodashjs.com/docs/lodash.map
 * @tutorial https://underscorejs.net/#map
 */
export const array_map = (array: any[], iteratee: any, this_arg: any = null) => {
  let result: any[] = [];
  for (let key in array) {
    array_push(result, iteratee(array[key], key, array));
  }
  return result;
};

# array_none

遍历数组,使用 predicate 断言函数检测数组内的所有元素是否都能通过测试。如果所有元素都不通过就返回 true,否则返回 false

数组

添加版本

0.0.1

语法

array_none(array, predicate(element,, this_arg);

参数

  • array(Array): 需要处理的数组。
  • predicate(element,(*): index, array)每次迭代调用的函数。
    • element(*): 当前遍历到的元素。
    • index(Number): 当前遍历到的索引。
    • array(Array): 数组本身。
  • this_arg(*): 执行回调时用作 this 的对象。

返回值

(Boolean): 如果所有元素通过 predicate 断言函数检测后都返回真值,那么就返回 false,否则返回 true

示例

@langnang/js-func/test/array_none.tsx (opens new window)

import { array_none } from "../main";


describe("array_none", () => {
  it("main", () => { });
  it("MDN: 检测所有数组元素的大小", () => {
    function isBigEnough(element: any, index: number, array: any[]) {
      return element >= 10;
    }
    expect(array_none([12, 5, 8, 130, 44], isBigEnough)).toEqual(!false);
    expect(array_none([12, 54, 18, 130, 44], isBigEnough)).toEqual(!true);
  });
  it("Lodash", () => {
    expect(array_none([true, 1, null, 'yes'], Boolean)).toEqual(!false);
    // => false

    var users = [
      { 'user': 'barney', 'age': 36, 'active': false },
      { 'user': 'fred', 'age': 40, 'active': false }
    ];

    // The `_.matches` iteratee shorthand.
    // _.every(users, { 'user': 'barney', 'active': false });
    // => false

    // The `_.matchesProperty` iteratee shorthand.
    // _.every(users, ['active', false]);
    // => true

    // The `_.property` iteratee shorthand.
    // _.every(users, 'active');
    // => false

  });
  it("Underscore", () => {
    expect(array_none([2, 4, 5], function (num: any) { return num % 2 == 0; })).toEqual(!false);
  });
})

实现

  • Langnang.array_none

@langnang/js-func/src/array_none.ts (opens new window)

import { array_every } from "./array_every";

/**
 * @name array_none
 * @description 遍历数组,使用 `predicate` 断言函数检测数组内的所有元素是否都能通过测试。如果所有元素都不通过就返回 `true`,否则返回 `false` 。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} predicate(element, index, array)每次迭代调用的函数。
 * * @param {*} element 当前遍历到的元素。
 * * @param {Number} index 当前遍历到的索引。
 * * @param {Array} array 数组本身。
 * @param {*} this_arg 执行回调时用作 `this` 的对象。
 * @returns {Boolean} 如果所有元素通过 `predicate` 断言函数检测后都返回真值,那么就返回 `false`,否则返回 `true` 。
 */
export const array_none = (array: any[], predicate: any, this_arg: any = null) => !array_every(array, predicate, this_arg)

# array_offset

将指定数量的元素移动到数组的末尾。

数组

添加版本

0.0.1

语法

array_offset(array, [length = 1]);

参数

  • array(Array): 需要处理的数组。
  • [length = 1](Number): 指定移动的元素个数。

返回值

(Array): 移动后的数组。

示例

@langnang/js-func/test/array_offset.tsx (opens new window)

import { array_offset } from '../main'

describe("array_offset", () => {
  it("main", () => {
    expect(array_offset([1, 2, 3, 4], 3)).toEqual([4, 1, 2, 3])
  });
})

参考

实现

  • Langnang.array_offset

@langnang/js-func/src/array_offset.ts (opens new window)

/**
 * @name array_offset
 * @description 将指定数量的元素移动到数组的末尾。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {Number} [length = 1] 指定移动的元素个数。
 * @returns {Array} 移动后的数组。
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/values
 */
export const array_offset = (array: any[], length: number = 1) => [
  ...array.slice(length),
  ...array.slice(0, length),
];

# array_pop

从数组中删除最后一个元素,并返回该元素的值。此方法更改原始数组。

数组

添加版本

0.0.1

语法

array_pop(array);

参数

  • array(Array): 需要处理的数组。

返回值

(*): 从数组中删除的元素(当数组为空时返回undefined)。

示例

@langnang/js-func/test/array_pop.tsx (opens new window)

import { array_pop } from '../main'

describe("array_pop", () => {
  it("main", () => {

  });
  it("MDN: 删除掉数组的最后一个元素", () => {
    const myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];

    const popped = array_pop(myFish);

    expect(myFish).toEqual(['angel', 'clown', 'mandarin']);

    expect(popped).toEqual('sturgeon');

  });
  it("Lodash", () => {

  });
  it("Underscore", () => {

  });
})

参考

实现

  • Langnang.array_pop

@langnang/js-func/src/array_pop.ts (opens new window)

/**
 * @name array_pop
 * @description 从数组中删除最后一个元素,并返回该元素的值。此方法更改原始数组。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @returns {*} 从数组中删除的元素(当数组为空时返回undefined)。
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/pop
 */
export const array_pop = (array: any[]) => {
  let value = array[array.length - 1];
  array.length = array.length - 1;
  return value;
};

# array_push

将一个或多个元素添加到数组的末尾,并返回该数组的新长度。此方法更改原始数组。

数组

添加版本

0.0.1

语法

array_push(array, values);

参数

  • array(Array): 需要处理的数组。
  • values(...*): 被添加到数组末尾的元素。

返回值

(Number): 返回数组的长度

示例

@langnang/js-func/test/array_push.tsx (opens new window)

import { array_push } from '../main'

describe("array_push", () => {
  it("main", () => {

  });
  it("MDN: 添加元素到数组", () => {
    var sports = ["soccer", "baseball"];
    var total = sports.push("football", "swimming");

    expect(sports).toEqual(["soccer", "baseball", "football", "swimming"]);

    expect(total).toEqual(4);

  });
  it("MDN: 合并两个数组", () => {
    var vegetables = ['parsnip', 'potato'];
    var moreVegs = ['celery', 'beetroot'];

    array_push(vegetables, ...moreVegs);

    expect(vegetables).toEqual(['parsnip', 'potato', 'celery', 'beetroot']);

  });
  it("Lodash", () => {

  });
  it("Underscore", () => {

  });
})

参考

实现

  • Langnang.array_push

@langnang/js-func/src/array_push.ts (opens new window)

/**
 * @name array_push
 * @description 将一个或多个元素添加到数组的末尾,并返回该数组的新长度。此方法更改原始数组。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {...*} values 被添加到数组末尾的元素。
 * @returns {Number} 返回数组的长度
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/push 
 */
export const array_push = (array: any[], ...values: any): number => {
  for (let i in values) {
    array[array.length] = values[i];
  }
  return array.length;
};

# array_reduce

遍历数组元素,每一次运行 iteratee 迭代函数会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。

数组

添加版本

0.0.1

语法

array_reduce(array, iteratee(element, index, array), initial_value);

参数

  • array(Array): 需要处理的数组。
  • iteratee(element, index, array)(*): 每次迭代调用的函数。
    • previous_value(*): 上一次调用 iteratee 时的返回值。
    • element(*): 当前遍历到的元素。
    • index(Number): 当前遍历到的索引。
    • array(Array): 数组本身。
  • initial_value(*): 作为第一次调用 iteratee 函数时参数 previous_value 的值。

返回值

(Array): 使用 iteratee 迭代函数遍历整个数组后的结果。

示例

@langnang/js-func/test/array_reduce.tsx (opens new window)

import { array_reduce } from '../main'

describe("array_reduce", () => {
  it("main", () => { });
  it("MDN: 求数组所有值的和", () => {
    let sum = array_reduce([0, 1, 2, 3], function (previousValue: any, currentValue: any) {
      return previousValue + currentValue
    }, 0)

    expect(sum).toEqual(6);

  });
  it("MDN: 累加对象数组里的值", () => {
    let initialValue = 0
    let sum = array_reduce([{ x: 1 }, { x: 2 }, { x: 3 }], function (previousValue: any, currentValue: any) {
      return previousValue + currentValue.x
    }, initialValue)

    expect(sum).toEqual(6);


  });
  it("MDN: 将二维数组转化为一维", () => {
    let flattened = array_reduce([[0, 1], [2, 3], [4, 5]],
      function (previousValue: any, currentValue: any) {
        return previousValue.concat(currentValue)
      },
      []
    )
    expect(flattened).toEqual([0, 1, 2, 3, 4, 5]);

  });
  it("MDN: 计算数组中每个元素出现的次数", () => {
    let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice']

    let countedNames = array_reduce(names, function (allNames: any, name: any) {
      if (name in allNames) {
        allNames[name]++
      }
      else {
        allNames[name] = 1
      }
      return allNames
    }, {})

    expect(countedNames).toEqual({ 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 });

  });
  it("MDN: 按属性对 object 分类", () => {
    let people = [
      { name: 'Alice', age: 21 },
      { name: 'Max', age: 20 },
      { name: 'Jane', age: 20 }
    ];

    function groupBy(objectArray: any, property: any) {
      return array_reduce(objectArray, function (acc: any, obj: any) {
        let key = obj[property]
        if (!acc[key]) {
          acc[key] = []
        }
        acc[key].push(obj)
        return acc
      }, {})
    }

    let groupedPeople = groupBy(people, 'age')

    expect(groupedPeople).toEqual({
      20: [
        { name: 'Max', age: 20 },
        { name: 'Jane', age: 20 }
      ],
      21: [{ name: 'Alice', age: 21 }]
    });

  });
  it("MDN: 使用扩展运算符和 initialValue 绑定包含在对象数组中的数组", () => {
    // friends - an array of objects
    // where object field "books" is a list of favorite books
    let friends = [{
      name: 'Anna',
      books: ['Bible', 'Harry Potter'],
      age: 21
    }, {
      name: 'Bob',
      books: ['War and peace', 'Romeo and Juliet'],
      age: 26
    }, {
      name: 'Alice',
      books: ['The Lord of the Rings', 'The Shining'],
      age: 18
    }]

    // allbooks - list which will contain all friends' books +
    // additional list contained in initialValue
    let allbooks = array_reduce(friends, function (previousValue: any, currentValue: any) {
      return [...previousValue, ...currentValue.books]
    }, ['Alphabet'])

    // allbooks = [
    //   'Alphabet', 'Bible', 'Harry Potter', 'War and peace',
    //   'Romeo and Juliet', 'The Lord of the Rings',
    //   'The Shining'
    // ]
    expect(allbooks).toEqual([
      'Alphabet', 'Bible', 'Harry Potter', 'War and peace',
      'Romeo and Juliet', 'The Lord of the Rings',
      'The Shining'
    ]);
  });
  it("MDN: 数组去重", () => {
    let myArray = ['a', 'b', 'a', 'b', 'c', 'e', 'e', 'c', 'd', 'd', 'd', 'd']
    let myArrayWithNoDuplicates = array_reduce(myArray, function (previousValue: any, currentValue: any) {
      if (previousValue.indexOf(currentValue) === -1) {
        previousValue.push(currentValue)
      }
      return previousValue
    }, [])

    expect(myArrayWithNoDuplicates).toEqual(['a', 'b', 'c', 'e', 'd']);
  });
  it("Lodash", () => {
    expect(array_reduce([1, 2], function (sum: any, n: any) {
      return sum + n;
    }, 0)).toEqual(3);
    // => 3

    // array_reduce({ 'a': 1, 'b': 2, 'c': 1 }, function (result, value, key) {
    //   (result[value] || (result[value] = [])).push(key);
    //   return result;
    // }, {});
    // => { '1': ['a', 'c'], '2': ['b'] } (无法保证遍历的顺序)
  });
  it("Underscore", () => {
    var sum = array_reduce([1, 2, 3], function (memo: any, num: any) { return memo + num; }, 0);

    expect(sum).toEqual(6);
  });
})

参考

实现

  • Langnang.array_reduce
  • Lodash.reduce
  • Underscore.reduce

@langnang/js-func/src/array_reduce.ts (opens new window)

/**
 * @name array_reduce
 * @description 遍历数组元素,每一次运行 `iteratee` 迭代函数会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} iteratee(element, index, array) 每次迭代调用的函数。
 * * @param {*} previous_value 上一次调用 `iteratee` 时的返回值。
 * * @param {*} element 当前遍历到的元素。
 * * @param {Number} index 当前遍历到的索引。
 * * @param {Array} array 数组本身。
 * @param {*} initial_value 作为第一次调用 `iteratee` 函数时参数 `previous_value` 的值。
 * @returns {Array} 使用 `iteratee` 迭代函数遍历整个数组后的结果。
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
 * @tutorial https://www.lodashjs.com/docs/lodash.reduce
 * @tutorial https://underscorejs.net/#reduce
 */
export const array_reduce = (array: any[], iteratee: any, initial_value: any) => {
  for (let i = 0; i <= array.length - 1; i++) {
    initial_value = iteratee(initial_value, array[i], i, array);
  }
  return initial_value;
};

# array_reduce_right

自右到左遍历数组元素,每一次运行 iteratee 迭代函数会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。

数组

添加版本

0.0.1

语法

array_reduce_right(array, iteratee(element, index, array), initial_value);

参数

  • array(Array): 需要处理的数组。
  • iteratee(element, index, array)(*): 每次迭代调用的函数。
    • previous_value(*): 上一次调用 iteratee 时的返回值。
    • element(*): 当前遍历到的元素。
    • index(Number): 当前遍历到的索引。
    • array(Array): 数组本身。
  • initial_value(*): 作为第一次调用 iteratee 函数时参数 previous_value 的值。

返回值

(Array): 使用 iteratee 迭代函数遍历整个数组后的结果。

示例

@langnang/js-func/test/array_reduce_right.tsx (opens new window)

import { array_reduce_right, array_reduce, array_concat } from '../main'

describe("array_reduce_right", () => {
  it("main", () => { });
  it("MDN: 求一个数组中所有值的和", () => {
    var sum = array_reduce_right([0, 1, 2, 3], function (a: any, b: any) {
      return a + b;
    });

    expect(sum).toEqual(6);

  });
  it("MDN: 扁平化(flatten)一个二维数组", () => {
    var flattened = array_reduce_right([[0, 1], [2, 3], [4, 5]], function (a: any, b: any) {
      return array_concat(a, b);
    }, []);
    expect(flattened).toEqual([4, 5, 2, 3, 0, 1]);
  });
  it("MDN: 运行一个带有回调每个函数将其结果传给下一个的异步函数列表", () => {
    const waterfall = (...functions: any) => (callback: any, ...args: any) =>
      array_reduce_right(functions,
        (composition: any, fn: any) => (...results: any) => fn(composition, ...results),
        callback
      )(...args);

    const randInt = (max: any) => Math.floor(Math.random() * max)

    const add5 = (callback: any, x: any) => {
      setTimeout(callback, randInt(1000), x + 5);
    };
    const mult3 = (callback: any, x: any) => {
      setTimeout(callback, randInt(1000), x * 3);
    };
    const sub2 = (callback: any, x: any) => {
      setTimeout(callback, randInt(1000), x - 2);
    };
    const split = (callback: any, x: any) => {
      setTimeout(callback, randInt(1000), x, x);
    };
    const add = (callback: any, x: any, y: any) => {
      setTimeout(callback, randInt(1000), x + y);
    };
    const div4 = (callback: any, x: any) => {
      setTimeout(callback, randInt(1000), x / 4);
    };

    // const computation = waterfall(add5, mult3, sub2, split, add, div4);
    // computation(console.log, 5) // -> 14

    // same as:

    const computation2 = (input: any, callback: any) => {
      const f6 = (x: any) => div4(callback, x);
      const f5 = (x: any, y: any) => add(f6, x, y);
      const f4 = (x: any) => split(f5, x);
      const f3 = (x: any) => sub2(f4, x);
      const f2 = (x: any) => mult3(f3, x);
      add5(f2, input);
    }

  });
  it("MDN: 展示 reduce 与 reduceRight 之间的区别", () => {
    var a = ['1', '2', '3', '4', '5'];
    var left = array_reduce(a, function (prev: any, cur: any) { return prev + cur; }, '');
    var right = array_reduce_right(a, function (prev: any, cur: any) { return prev + cur; }, '');

    expect(left).toEqual("12345");

    expect(right).toEqual("54321");

  });
  it("Lodash", () => {
    var array = [[0, 1], [2, 3], [4, 5]];

    expect(array_reduce_right(array, function (flattened: any, other: any) {
      return array_concat(flattened, other);
    }, [])).toEqual([4, 5, 2, 3, 0, 1]);

  });
  it("Underscore", () => {
    var list = [[0, 1], [2, 3], [4, 5]];
    var flat = array_reduce_right(list, function (a: any, b: any) { return array_concat(a, b); }, []);

    expect(flat).toEqual([4, 5, 2, 3, 0, 1])
  });
})

参考

实现

  • Langnang.array_reduce_right
  • Lodash.reduceRight
  • Underscore.reduceRight

@langnang/js-func/src/array_reduce_right.ts (opens new window)

/**
 * @name array_reduce_right
 * @description 自右到左遍历数组元素,每一次运行 `iteratee` 迭代函数会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} iteratee(element, index, array) 每次迭代调用的函数。
 * * @param {*} previous_value 上一次调用 `iteratee` 时的返回值。
 * * @param {*} element 当前遍历到的元素。
 * * @param {Number} index 当前遍历到的索引。
 * * @param {Array} array 数组本身。
 * @param {*} initial_value 作为第一次调用 `iteratee` 函数时参数 `previous_value` 的值。
 * @returns {Array} 使用 `iteratee` 迭代函数遍历整个数组后的结果。
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/ReduceRight
 * @tutorial https://www.lodashjs.com/docs/lodash.reduceRight
 * @tutorial https://underscorejs.net/#reduceRight
 */
export const array_reduce_right = (array: any[], iteratee: any, initial_value: any) => {
  for (let i = array.length - 1; i >= 0; i--) {
    initial_value = iteratee(initial_value, array[i], i, array);
  }
  return initial_value;
};

# array_rest

返回数组中不包含前n个元素的其它元素

数组

添加版本

0.0.1

语法

array_rest(array, [n = 1]);

参数

  • array(Array): 需要处理的数组。
  • [n = 1](Number): 不包含的元素个数。

返回值

(Array): 处理后的数组。

示例

@langnang/js-func/test/array_rest.tsx (opens new window)

import { array_rest } from '../main'

describe("array_rest", () => {
  it("main", () => {
    expect(array_rest([1, 2, 3, 4], 3)).toEqual([4])
  });
})

实现

  • Langnang.array_rest

@langnang/js-func/src/array_rest.ts (opens new window)

import { array_slice } from "./array_slice";

/**
 * @name array_rest
 * @description 返回数组中不包含前n个元素的其它元素
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {Number} [n = 1] 不包含的元素个数。
 * @returns {Array} 处理后的数组。
 */
export const array_rest = (array: any[], n: number = 1): any[] => array_slice(array, n)

# array_reverse

反转数组,将数组中元素的位置颠倒,并返回该数组。此方法更改原始数组。

数组

添加版本

0.0.1

语法

array_reverse(array);

参数

  • array(Array): 需要处理的数组。

返回值

(Array): 反转后的数组。

示例

@langnang/js-func/test/array_reverse.tsx (opens new window)

import { array_reverse } from '../main'

describe("array_reverse", () => {
  it("main", () => { });
  it("MDN: 颠倒数组中的元素", () => {
    const a = [1, 2, 3];

    expect(a).toEqual([1, 2, 3]);

    array_reverse(a);

    expect(a).toEqual([3, 2, 1]);

  });
  it("Lodash", () => {
    var array = [1, 2, 3];

    expect(array_reverse(array)).toEqual(array);

  });
  it("Underscore", () => { });
})

参考

实现

  • Langnang.array_reverse
  • Lodash.reverse

@langnang/js-func/src/array_reverse.ts (opens new window)

/**
 * @name array_reverse
 * @description 反转数组,将数组中元素的位置颠倒,并返回该数组。此方法更改原始数组。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @returns {Array} 反转后的数组。
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse
 * @tutorial https://www.lodashjs.com/docs/lodash.reverse
 */
export const array_reverse = (array: any[]) => {
  let count: number = Math.floor(array.length / 2);
  for (let i = 0; i <= count - 1; i++) {
    [array[i], array[array.length - 1 - i]] = [array[array.length - 1 - i], array[i]];
  }
  return array;
};

# array_shift

删除数组的第一个元素,并返回该元素的值。此方法更改原始数组。

数组 更改原始数据

添加版本

0.0.1

语法

array_shift(array);

参数

  • array(Array): 需要处理的数组。

返回值

(*): 从数组中删除的元素; 如果数组为空则返回 undefined 。

示例

@langnang/js-func/test/array_shift.tsx (opens new window)

import { array_shift } from '../main'

describe("array_shift", () => {
  it("main", () => { });
  it("MDN: 移除数组中的一个元素", () => {
    let myFish = ['angel', 'clown', 'mandarin', 'surgeon'];

    expect(myFish).toEqual(['angel', 'clown', 'mandarin', 'surgeon']);

    var shifted = array_shift(myFish);

    expect(shifted).toEqual('angel');

    // console.log(myFish)
    // expect(myFish).toEqual(['clown', 'mandarin', 'surgeon']);


  });
  it("MDN: 在 while 循环中使用 shift()", () => {
    var names = ["Andrew", "Edward", "Paul", "Chris", "John"];
    let i;

    // while ((i = array_shift(names)) !== undefined) {
    // console.log(i, names);
    // }
    // Andrew, Edward, Paul, Chris, John

  });
  it("Lodash", () => { });
  it("Underscore", () => { });
})

参考

实现

  • Langnang.array_shift

@langnang/js-func/src/array_shift.ts (opens new window)

import { array_slice } from "./array_slice";
/**
 * @name array_shift
 * @description 删除数组的第一个元素,并返回该元素的值。此方法更改原始数组。
 * @category Array 数组
 * @category Update 更改原始数据
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @returns {*} 从数组中删除的元素; 如果数组为空则返回 undefined 。
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/shift
 */
export const array_shift = (array: any[]) => {
  const shift = array[0];
  array = array_slice(array, 1);
  return shift;
};

# array_slice

裁剪数组,从 start 位置开始到 end 结束,但不包括 end 本身的位置。

数组

添加版本

0.0.1

语法

array_slice(array, [begin = 0], [end = array.length]);

参数

  • array(Array): 需要处理的数组。
  • [begin = 0](Number): 开始位置。
  • [end = array.length](Number): 结束位置。

返回值

(Array): 返回数组裁剪部分的新数组。

示例

@langnang/js-func/test/array_slice.tsx (opens new window)

import { array_slice } from '../main'

describe("array_slice", () => {
  it("main", () => { });
  it("MDN", () => {
    const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];

    expect(array_slice(animals, 2)).toEqual(["camel", "duck", "elephant"]);

    expect(array_slice(animals, 2, 4)).toEqual(["camel", "duck"]);

    expect(array_slice(animals, 1, 5)).toEqual(["bison", "camel", "duck", "elephant"]);

    expect(array_slice(animals, -2)).toEqual(["duck", "elephant"]);

    expect(array_slice(animals, 2, -1)).toEqual(["camel", "duck"]);

    expect(array_slice(animals,)).toEqual(["ant", "bison", "camel", "duck", "elephant"]);

  });
  it("MDN: 返回现有数组的一部分", () => {
    var fruits = ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango'];
    var citrus = array_slice(fruits, 1, 3);

    expect(fruits).toEqual(['Banana', 'Orange', 'Lemon', 'Apple', 'Mango']);

    expect(citrus).toEqual(['Orange', 'Lemon']);

  });
  it("Lodash", () => { });
  it("Underscore", () => { });
})

参考

实现

  • Langnang.array_slice
  • Lodash.slice

@langnang/js-func/src/array_slice.ts (opens new window)

import { _from_index } from "./_form_index";
/**
 * @name array_slice
 * @description 裁剪数组,从 start 位置开始到 end 结束,但不包括 end 本身的位置。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {Number} [begin = 0] 开始位置。
 * @param {Number} [end = array.length] 结束位置。
 * @returns {Array} 返回数组裁剪部分的新数组。
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
 * @tutorial https://www.lodashjs.com/docs/lodash.slice
 */
export const array_slice = (array: any[], begin: number = 0, end: number = array.length) => {
  // 如果提取起始处索引为负数,则表示从原数组中倒数第几个元素开始提起
  if (begin < 0) {
    begin = array.length + begin;
  }
  // 如果 begin 大于原数组的长度,则会返回空数组
  if (begin > array.length - 1) {
    return [];
  }
  // 如果提取终止处索引为负数, 则它表示在原数组中的倒数第几个元素结束抽取。
  if (end < 0) {
    end = array.length + end;
  }
  // 如果 end 大于数组的长度,slice 也会一直提取到原数组末尾。
  if (end > array.length) {
    end = array.length;
  }
  let _arr = [];
  let index = 0;
  while (end - begin > 0) {
    _arr[index] = array[begin];
    index++;
    begin++;
  }
  return _arr;
};

# array_some

遍历数组,通过 predicate 断言函数检测数组中的元素是否存在任意元素通过测试。如果存在元素能通过就返回 true,否则返回 false

数组

添加版本

0.0.1

语法

array_some(array, predicate(element, index, array), this_arg);

参数

  • array(Array): 需要处理的数组。
  • predicate(element, index, array)(*): 每次迭代调用的函数。
    • element(*): 当前遍历到的元素。
    • index(Number): 当前遍历到的索引。
    • array(Array): 数组本身。
  • this_arg(*): 执行回调时用作 this 的对象。

返回值

(Boolean): 如果存在元素通过 predicate 断言函数检测后返回真值,那么就返回 true,否则返回 false

示例

@langnang/js-func/test/array_some.tsx (opens new window)

import { array_some } from '../main'

describe("array_some", () => {
  it("main", () => { });
  it("MDN", () => {
    const array = [1, 2, 3, 4, 5];

    // checks whether an element is even
    const even = (element: any) => element % 2 === 0;

    expect(array_some(array, even)).toEqual(true);

  });
  it("MDN: 测试数组元素的值", () => {
    function isBiggerThan10(element: any, index: any, array: any) {
      return element > 10;
    }

    expect(array_some([2, 5, 8, 1, 4], isBiggerThan10)).toEqual(false);  // false
    expect(array_some([12, 5, 8, 1, 4], isBiggerThan10)).toEqual(true); // true

  });
  it("MDN: 使用箭头函数测试数组元素的值", () => {
    expect(array_some([2, 5, 8, 1, 4], (x: any) => x > 10)).toEqual(false);  // false
    expect(array_some([12, 5, 8, 1, 4], (x: any) => x > 10)).toEqual(true); // true

  });
  it("MDN: 判断数组元素中是否存在某个值", () => {
    var fruits = ['apple', 'banana', 'mango', 'guava'];

    function checkAvailability(arr: any, val: any) {
      return array_some(arr, function (arrVal: any) {
        return val === arrVal;
      });
    }

    expect(checkAvailability(fruits, 'kela')).toEqual(false);   // false
    expect(checkAvailability(fruits, 'banana')).toEqual(true); // true

  });
  it("MDN: 使用箭头函数判断数组元素中是否存在某个值", () => {
    var fruits = ['apple', 'banana', 'mango', 'guava'];

    function checkAvailability(arr: any, val: any) {
      return array_some(arr, (arrVal: any) => val === arrVal);
    }

    expect(checkAvailability(fruits, 'kela')).toEqual(false);   // false
    expect(checkAvailability(fruits, 'banana')).toEqual(true); // true

  });
  it("MDN: 将任意值转换为布尔类型", () => {
    var TRUTHY_VALUES = [true, 'true', 1];

    function getBoolean(value: any) {
      'use strict';

      if (typeof value === 'string') {
        value = value.toLowerCase().trim();
      }

      return array_some(TRUTHY_VALUES, function (t: any) {
        return t === value;
      });
    }

    expect(getBoolean(false)).toEqual(false);   // false
    expect(getBoolean('false')).toEqual(false); // false
    expect(getBoolean(1)).toEqual(true);       // true
    expect(getBoolean('true')).toEqual(true);  // true

  });
  it("Lodash", () => {
    expect(array_some([null, 0, 'yes', false], Boolean)).toEqual(true);

    var users = [
      { 'user': 'barney', 'active': true },
      { 'user': 'fred', 'active': false }
    ];

    // The `_.matches` iteratee shorthand.
    // _.some(users, { 'user': 'barney', 'active': false });
    // => false

    // The `_.matchesProperty` iteratee shorthand.
    // _.some(users, ['active', false]);
    // => true

    // The `_.property` iteratee shorthand.
    // _.some(users, 'active');
    // => true

  });
  it("Underscore", () => { });
})

参考

实现

  • Langnang.array_some
  • Lodash.some

@langnang/js-func/src/array_some.ts (opens new window)

/**
 * @name array_some
 * @description 遍历数组,通过 `predicate` 断言函数检测数组中的元素是否存在任意元素通过测试。如果存在元素能通过就返回 `true`,否则返回 `false` 。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} predicate(element, index, array) 每次迭代调用的函数。
 * * @param {*} element 当前遍历到的元素。
 * * @param {Number} index 当前遍历到的索引。
 * * @param {Array} array 数组本身。
 * @param {*} this_arg 执行回调时用作 `this` 的对象。
 * @returns {Boolean} 如果存在元素通过 `predicate` 断言函数检测后返回真值,那么就返回 `true`,否则返回 `false` 。
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/some
 * @tutorial https://www.lodashjs.com/docs/lodash.some
 */
export const array_some = (array: any[], predicate: Function, this_arg: any = null) => {
  for (let key in array) {
    if (predicate(array[key], key, array)) return true;
  }
  return false;
};

# array_sort

使用原地算法对数组的元素进行排序,并返回数组。此方法更改原始数组。

数组

添加版本

0.0.1

语法

array_sort(array, iteratee(element, index, array));

参数

  • array(Array): 需要处理的数组。
  • iteratee(element, index, array)(*): 每次迭代调用的函数。
    • a(*): 第一个用于比较的元素。
    • b(*): 第二个用于比较的元素。

返回值

(Array): 排序后的数组。

示例

@langnang/js-func/test/array_sort.tsx (opens new window)

import { array_sort } from '../main'

describe("array_sort", () => {
  it("main", () => { });
  it("MDN", () => {
    const months = ['March', 'Jan', 'Feb', 'Dec'];

    array_sort(months);
    expect(months).toEqual(["Dec", "Feb", "Jan", "March"]);

    const array1 = [1, 30, 4, 21, 100000];

    array_sort(array1);

    expect(array1).toEqual([1, 100000, 21, 30, 4]);

  });
  it("MDN: 创建、显示及排序数组", () => {
    var stringArray = ["Blue", "Humpback", "Beluga"];
    var numericStringArray = ["80", "9", "700"];
    var numberArray = [40, 1, 5, 200];
    var mixedNumericArray = ["80", "9", "700", 40, 1, 5, 200];

    function compareNumbers(a: any, b: any) {
      return a - b;
    }


    expect(array_sort([...stringArray])).toEqual([...stringArray].sort());

    expect(array_sort([...numberArray], compareNumbers)).toEqual([...numberArray].sort(compareNumbers));

    expect(array_sort([...numericStringArray], compareNumbers)).toEqual([...numericStringArray].sort(compareNumbers));

    expect(array_sort([...mixedNumericArray], compareNumbers)).toEqual([...mixedNumericArray].sort(compareNumbers));

  });
  it("MDN: 对非 ASCII 字符排序", () => {
    var items = ['réservé', 'premier', 'cliché', 'communiqué', 'café', 'adieu'];
    array_sort(items, function (a: any, b: any) {
      return a.localeCompare(b);
    });

    expect(items).toEqual(['adieu', 'café', 'cliché', 'communiqué', 'premier', 'réservé']);

  });
  it("MDN: 使用映射改善排序", () => {
    // 需要被排序的数组
    var list = ['Delta', 'alpha', 'CHARLIE', 'bravo'];

    // 对需要排序的数字和位置的临时存储
    var mapped = list.map(function (el: any, i: any) {
      return { index: i, value: el.toLowerCase() };
    })

    // 按照多个值排序数组
    mapped.sort(function (a: any, b: any) {
      return +(a.value > b.value) || +(a.value === b.value) - 1;
    });

    // 根据索引得到排序的结果
    var result = mapped.map(function (el: any) {
      return list[el.index];
    });

  });
  it("Lodash", () => { });
  it("Underscore", () => { });
})

参考

实现

  • Langnang.array_sort

@langnang/js-func/src/array_sort.ts (opens new window)

/**
 * @name array_sort
 * @description 使用原地算法对数组的元素进行排序,并返回数组。此方法更改原始数组。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} iteratee(element, index, array) 每次迭代调用的函数。
 * * @param {*} a 第一个用于比较的元素。
 * * @param {*} b 第二个用于比较的元素。
 * @returns {Array} 排序后的数组。
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
 */
export const array_sort = (array: any[], iteratee: any = null): any[] => {
  // in-place 原地算法
  if (!iteratee) iteratee = array_sort_iteratee;

  let index = 0;
  while (index < array.length) {
    for (let i = index; i <= array.length - 1; i++) {
      let compare = iteratee(array[index], array[i]);
      if (compare > 0) {
        [array[index], array[i]] = [array[i], array[index]];
      }
    }
    index++;
  }
  return array;
};

export const array_sort_iteratee = (a: any, b: any): any => {
  return a.toLocaleString().localeCompare(b.toLocaleString());
}

export const array_sort_iteratee_charat = (a: any, b: any, index: number = 0): any => {
  let result = a.toLocaleString().charCodeAt(index) - b.toLocaleString().charCodeAt(index);
  if (result == 0) {
    return array_sort_iteratee_charat(a, b, index + 1);
  } else {
    return result;
  }
}

# array_sorted

检测数组是否已排序。如果数组按升序排序,则返回 1;如果按降序排序,则返回 -1;如果未排序,则返回 0。

数组

添加版本

0.0.1

语法

array_sorted(array, iteratee(element, index, array));

参数

  • array(Array): 需要处理的数组。
  • iteratee(element, index, array)(*): 每次迭代调用的函数。
    • a(*): 第一个用于比较的元素。
    • b(*): 第二个用于比较的元素。

返回值

(Number): 检测的结果。

示例

@langnang/js-func/test/array_sorted.tsx (opens new window)

import { array_sorted } from '../main'

describe("array_sorted", () => {
  it("main", () => {
    expect(array_sorted(['March', 'Jan', 'Feb', 'Dec'])).toEqual(1);
    expect(array_sorted(['Dec', 'Feb', 'Jan', 'March'])).toEqual(-1);
    expect(array_sorted(['March', 'Feb', 'Jan', 'Dec'])).toEqual(0);
  });
})

参考

实现

  • Langnang.array_sorted

@langnang/js-func/src/array_sorted.ts (opens new window)

import { array_sort_iteratee_charat } from "./array_sort";

/**
 * @name array_sorted
 * @description 检测数组是否已排序。如果数组按升序排序,则返回 1;如果按降序排序,则返回 -1;如果未排序,则返回 0。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} iteratee(element, index, array) 每次迭代调用的函数。
 * * @param {*} a 第一个用于比较的元素。
 * * @param {*} b 第二个用于比较的元素。
 * @returns {Number} 检测的结果。
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
 */
export const array_sorted = (array: any[], iteratee: any = null) => {
  if (!iteratee) iteratee = array_sort_iteratee_charat;
  let i = 1,
    is_sorted = iteratee(array[0], array[1]) > 1 ? 1 : -1;
  while (i < array.length) {
    if (is_sorted !== (iteratee(array[i - 1], array[i]) > 1 ? 1 : -1)) {
      return 0;
    }
    i++;
  }
  return is_sorted;
};

# array_splice

通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。

数组

添加版本

0.0.1

语法

array_splice(array, [start = 0], [delete_count = array.length - start], values 要添加进数组的元素,从start 位置开始。如果不指定,则 splice());

参数

  • array(Array): 需要处理的数组。
  • [start = 0](Number): 指定修改的开始位置(从 0 计数)。
  • [delete_count = array.length - start](Number): 表示要移除的数组元素的个数。
  • values 要添加进数组的元素,从start 位置开始。如果不指定,则 splice()(...*): 将只删除数组元素。

返回值

由被删除的元素组成的一个数组。:

示例

@langnang/js-func/test/array_splice.tsx (opens new window)

import { array_splice } from '../main'

describe("array_splice", () => {
  it("main", () => { });
  it("MDN", () => {
    const months = ['Jan', 'March', 'April', 'June'];
    array_splice(months, 1, 0, 'Feb');

    expect(months).toEqual(["Jan", "Feb", "March", "April", "June"]);

    array_splice(months, 4, 1, 'May');

    expect(months).toEqual(["Jan", "Feb", "March", "April", "May"]);

  });
  it("MDN: 从索引 2 的位置开始删除 0 个元素,插入“drum”", () => {
    var myFish = ["angel", "clown", "mandarin", "sturgeon"];

    expect([...myFish].splice(2, 0, 'drum')).toEqual(array_splice([...myFish], 2, 0, 'drum'));

  });
  it("MDN: 从索引 2 的位置开始删除 0 个元素,插入“drum”和 “guitar”", () => {
    var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];

    expect([...myFish].splice(2, 0, 'drum', 'guitar')).toEqual(array_splice([...myFish], 2, 0, 'drum', 'guitar'));

  });
  it("MDN: 从索引 3 的位置开始删除 1 个元素", () => {
    var myFish = ['angel', 'clown', 'drum', 'mandarin', 'sturgeon'];

    expect([...myFish].splice(3, 1)).toEqual(array_splice([...myFish], 3, 1));
  });
  it("MDN: 从索引 0 的位置开始删除 2 个元素,插入\"parrot\"、\"anemone\"和\"blue\"", () => {
    var myFish = ['angel', 'clown', 'trumpet', 'sturgeon'];

    expect([...myFish].splice(0, 2, 'parrot', 'anemone', 'blue')).toEqual(array_splice([...myFish], 0, 2, 'parrot', 'anemone', 'blue'));

  });
  it("MDN: 从索引 2 的位置开始删除 2 个元素", () => {
    var myFish = ['parrot', 'anemone', 'blue', 'trumpet', 'sturgeon'];

    expect([...myFish].splice(myFish.length - 3, 2)).toEqual(array_splice([...myFish], myFish.length - 3, 2));
  });
  it("MDN: 从索引 -2 的位置开始删除 1 个元素", () => {
    var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];

    expect([...myFish].splice(-2, 1)).toEqual(array_splice([...myFish], -2, 1));
  });
  it("MDN: 从索引 2 的位置开始删除所有元素", () => {
    var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];

    expect([...myFish].splice(2)).toEqual(array_splice([...myFish], 2));

  });
  it("Lodash", () => { });
  it("Underscore", () => { });
})

参考

实现

  • Langnang.array_splice

@langnang/js-func/src/array_splice.ts (opens new window)

import { _from_index } from "./_form_index";
import { array_slice } from "./array_slice";
import { array_push } from "./array_push";
/**
 * @name array_splice
 * @description 通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {Number} [start = 0] 指定修改的开始位置(从 0 计数)。
 * @param {Number} [delete_count = array.length - start] 表示要移除的数组元素的个数。
 * @param {...*} values 要添加进数组的元素,从start 位置开始。如果不指定,则 splice() 将只删除数组元素。
 * @returns 由被删除的元素组成的一个数组。
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
 */
export const array_splice = (array: any[], start = 0, delete_count = array.length - start, ...values: any) => {
  start = _from_index(array.length, start);
  let delete_array: any[] = [];
  // 删除元素
  for (let i = 0; i < delete_count; i++) {
    array_push(delete_array, array[i + start]);
    delete (array[i + start]);
  }
  // 添加元素
  let rest_array = [...values, ...array_slice(array, start + delete_count)];
  for (let i = 0; i < rest_array.length; i++) {
    array[i + start] = rest_array[i];
  }
  return delete_array;
};

# array_unique

返回数组的所有的不同元素值(去重)

数组

添加版本

0.0.1

语法

array_unique(array, iteratee);

参数

  • array(Array): 需要处理的数组。
  • iteratee(*):

返回值

(Array): 去重后的数组。

示例

@langnang/js-func/test/array_unique.tsx (opens new window)

import { array_unique } from '../main'

describe("array_unique", () => {
  it("main", () => { });
  it("Lodash.uniq", () => {
    expect(array_unique([2, 1, 2])).toEqual([2, 1]);
  });
  it("Lodash.uniqBy", () => {
    expect(array_unique([2.1, 1.2, 2.3], Math.floor)).toEqual([2.1, 1.2]);

    // The `_.property` iteratee shorthand.
    // _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
    // => [{ 'x': 1 }, { 'x': 2 }]
  });
  it("Lodash.uniqWith", () => {
    var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];

    // _.uniqWith(objects, _.isEqual);
    // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
  });
  it("Underscore.uniq", () => {
    expect(array_unique([1, 2, 1, 4, 1, 3])).toEqual([1, 2, 4, 3]);
  });
})

参考

实现

  • Langnang.array_unique
  • Lodash.uniq
  • Lodash.uniqBy
  • Lodash.uniqWith
  • Underscore.uniq

@langnang/js-func/src/array_unique.ts (opens new window)

import { array_includes } from "./array_includes";
import { array_push } from "./array_push";

/**
 * @name array_unique
 * @description 返回数组的所有的不同元素值(去重)
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} iteratee
 * @returns {Array} 去重后的数组。
 * @tutorial https://www.lodashjs.com/docs/lodash.uniq
 * @tutorial https://www.lodashjs.com/docs/lodash.uniqBy
 * @tutorial https://www.lodashjs.com/docs/lodash.uniqWith
 * @tutorial https://underscorejs.net/#uniq
 */
export const array_unique = (array: any[], iteratee: any = null): any[] => {
  let iteratee_array: any[] = [],
    result: any[] = [];
  for (let i = 0; i < array.length; i++) {
    let value = iteratee ? iteratee(array[i]) : array[i];
    if (!array_includes(iteratee_array, value)) {
      array_push(iteratee_array, value);
      array_push(result, array[i]);
    }
  }
  return result;
}

export const array_unique_iteratee = (array: any[]): any[] => [...new Set(array)];

# array_unshift

将一个或多个元素添加到数组的开头,并返回该数组的新长度。此方法更改原始数组。

数组

添加版本

0.0.1

语法

array_unshift(array, values);

参数

  • array(Array): 需要处理的数组。
  • values(...*): 被添加到数组末尾的元素。

返回值

(Number): 返回数组的长度

示例

@langnang/js-func/test/array_unshift.tsx (opens new window)

import { array_unshift } from '../main'

describe("array_unshift", () => {
  it("main", () => { });
  it("MDN", () => {
    const array1 = [1, 2, 3];

    expect(array_unshift(array1, 4, 5)).toEqual(5);

    expect(array1).toEqual([4, 5, 1, 2, 3]);

  });
  it("MDN: 使用 unshift()", () => {
    const arr = [1, 2];

    expect(array_unshift(arr, 0)).toEqual(3);
    expect(arr).toEqual([0, 1, 2]);

    expect(array_unshift(arr, -2, -1)).toEqual(5);
    expect(arr).toEqual([-2, -1, 0, 1, 2]);


    expect(array_unshift(arr, [-4, -3])).toEqual(6);
    expect(arr).toEqual([[-4, -3], -2, -1, 0, 1, 2]);

    expect(array_unshift(arr, [-7, -6], [-5])).toEqual(8);
    expect(arr).toEqual([[-7, -6], [-5], [-4, -3], -2, -1, 0, 1, 2]);

  });
  it("Lodash", () => { });
  it("Underscore", () => { });
})

参考

实现

  • Langnang.array_unshift

@langnang/js-func/src/array_unshift.ts (opens new window)

/**
 * @name array_unshift
 * @description 将一个或多个元素添加到数组的开头,并返回该数组的新长度。此方法更改原始数组。
 * @category Array 数组
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {...*} values 被添加到数组末尾的元素。
 * @returns {Number} 返回数组的长度
 * @tutorial https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift 
 */
export const array_unshift = (array: any[], ...values: any): number => {
  let merge_array = [...values, ...array];
  for (let i = 0; i < merge_array.length; i++) {
    array[i] = merge_array[i];
  }
  return array.length;
};

# avg

计算平均值

undefined

添加版本

0.0.2

语法

avg(nums);

参数

  • nums(...Number): 需要计算的数值

实现

  • Langnang.avg

@langnang/js-func/src/avg.ts (opens new window)

import { sum } from "./sum";

/**
 * @name avg
 * @description 计算平均值
 * @category Math
 * @since 0.0.2
 * @param {...Number} nums 需要计算的数值
 * @returns{Number} 计算的结果
 */
export const avg = (...nums: number[]) => sum(nums) / nums.length;

# bubble_sort

冒泡排序。重复遍历比较相邻元素,将最大/小元素移至末尾,并逐渐减少遍历长度

数组 算法 排序

算法原理

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  2. 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

添加版本

0.0.1

语法

bubble_sort(array, iteratee(element, index, array));

参数

  • array(Array): 需要处理的数组。
  • iteratee(element, index, array)(*): 每次迭代调用的函数。
    • a(*): 第一个用于比较的元素。
    • b(*): 第二个用于比较的元素。

返回值

(Array): 排序后的数组。

示例

@langnang/js-func/test/bubble_sort.tsx (opens new window)

import { bubble_sort } from '../main'

describe("bubble_sort", () => {
  it("main", () => {
    const array = [1, 5, 3, 6, 4, 8, 2, 9, 7];

    expect(bubble_sort(array)).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9])
  });
})

实现

  • Langnang.bubble_sort

@langnang/js-func/src/bubble_sort.ts (opens new window)

/**
 * @name bubble_sort
 * @description 冒泡排序。重复遍历比较相邻元素,将最大/小元素移至末尾,并逐渐减少遍历长度
 * @category Array 数组
 * @category Algorithm 算法
 * @category Sorting 排序
 * @tip 算法原理 tip 1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。\n2. 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。\n3. 针对所有的元素重复以上的步骤,除了最后一个。\n4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。\n
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} iteratee(element, index, array) 每次迭代调用的函数。
 * * @param {*} a 第一个用于比较的元素。
 * * @param {*} b 第二个用于比较的元素。
 * @returns {Array} 排序后的数组。
 */
export const bubble_sort = (array: any[], iteratee: any = null): any[] => {
  // 冒泡:将比较数组内的最大值移至末尾

  let i = array.length;
  // 由于每次遍历将最大值移至末尾,因此逐渐减少比较长度
  while (i > 0) {
    bubble(array, i);
    i--;
  }
  return array;
};
const bubble = (array: any[], length: number) => {
  for (let i = 0; i < length - 1; i++) {
    // 比较相邻元素,检测是否需要交换位置
    if (array[i] > array[i + 1]) {
      // 交换元素位置
      [array[i], array[i + 1]] = [array[i + 1], array[i]];
    }
  }
};
/**
 * 冒泡排序比较方法
 */
const bubble_sort_iteratee = () => { }

# bucket_sort

桶排序。设置桶范围,遍历数据至对应的桶中,对非空桶进行排序后拼接

数组 算法 排序

算法原理

  1. 人为设置一个 BucketSize,作为每个桶所能放置多少个不同数值(例如当 BucketSize==5 时,该桶可以存放{1,2,3,4,5}这几种数字,但是容量不限,即可以存放 100 个 3);
  2. 遍历输入数据,并且把数据一个一个放到对应的桶里去;
  3. 对每个不是空的桶进行排序,可以使用其它排序方法,也可以递归使用桶排序;
  4. 从不是空的桶里把排好序的数据拼接起来。

添加版本

0.0.1

语法

bucket_sort(array, iteratee(element, index, array));

参数

  • array(Array): 需要处理的数组。
  • iteratee(element, index, array)(*): 每次迭代调用的函数。
    • a(*): 第一个用于比较的元素。
    • b(*): 第二个用于比较的元素。

返回值

(Array): 排序后的数组。

示例

@langnang/js-func/test/bucket_sort.tsx (opens new window)

import { bucket_sort } from '../main'

describe("bucket_sort", () => {
  it("main", () => {
    const array = [1, 5, 3, 6, 4, 8, 2, 9, 7];

    expect(bucket_sort(array)).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9])
  });
})

实现

  • Langnang.bucket_sort

@langnang/js-func/src/bucket_sort.ts (opens new window)

/**
 * @name bucket_sort
 * @description 桶排序。设置桶范围,遍历数据至对应的桶中,对非空桶进行排序后拼接
 * @category Array 数组
 * @category Algorithm 算法
 * @category Sorting 排序
 * @tip 算法原理 tip 1. 人为设置一个 BucketSize,作为每个桶所能放置多少个不同数值(例如当 BucketSize==5 时,该桶可以存放{1,2,3,4,5}这几种数字,但是容量不限,即可以存放 100 个 3);\n2. 遍历输入数据,并且把数据一个一个放到对应的桶里去;\n3. 对每个不是空的桶进行排序,可以使用其它排序方法,也可以递归使用桶排序;\n4. 从不是空的桶里把排好序的数据拼接起来。\n
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} iteratee(element, index, array) 每次迭代调用的函数。
 * * @param {*} a 第一个用于比较的元素。
 * * @param {*} b 第二个用于比较的元素。
 * @returns {Array} 排序后的数组。
 */
export const bucket_sort = (array: any[]): any[] => {
  // 声明一个空桶, 将数据压入桶中
  const bucket = new Array(Math.max(...array) + 1);
  bucket.fill(0);
  array.forEach((one) => {
    bucket[one]++
  });
  // 声明一个新数组, 当做排序后的数组
  const newArr: any[] = []
  bucket.forEach((one, index) => {
    for (let i = 0; i < one; i++) {
      newArr.push(index)
    }
  })

  return newArr;
}

# charcode_compare

比较两个元素的 Unicode 编码大小

添加版本

0.0.1

语法

charcode_compare(a, b);

参数

  • a(*): 第一个元素
  • b(*): 第二个元素

返回值

(Number): 返回比较结果。0:相等,1:a>b,-1:a<b;

示例

@langnang/js-func/test/charcode_compare.tsx (opens new window)

import { charcode_compare } from '../main'

describe("charcode_compare", () => {
  it("main", () => {
    expect(charcode_compare(0, 1)).toEqual(-1);

    expect(charcode_compare(1, 0)).toEqual(1);

    expect(charcode_compare(1, 1)).toEqual(0);

    expect(charcode_compare("", "")).toEqual(0);
  });
})

实现

  • Langnang.charcode_compare

@langnang/js-func/src/charcode_compare.ts (opens new window)

/**
 * @name charcode_compare
 * @description 比较两个元素的 Unicode 编码大小
 * @since 0.0.1
 * @param {*} a 第一个元素
 * @param {*} b 第二个元素
 * @returns {Number} 返回比较结果。0:相等,1:a>b,-1:a<b;
 */
export const charcode_compare = (a: any, b: any, iteratee: any = null): number => {
  if (!iteratee) iteratee = charcode_compare_iteratee;
  return iteratee(a, b);
}
/**
 * *@name charcode_compare_iteratee
 * *@description 默认 `iteratee` 断言方法
 * *@param {*} a 第一个元素
 * *@param {*} b 第二个元素
 * *@param {Number} [index = 0] 比较字符所在元素的位置下标
 * *@returns {Number} 返回比较结果。0:相等,1:a>b,-1:a<b;
 */
export const charcode_compare_iteratee = (a: any, b: any, index: number = 0): number => {
  const result = String(a).charCodeAt(index) - String(b).charCodeAt(index);
  if (result === 0 && (String(a).charAt(index) || String(b).charAt(index))) {
    return charcode_compare_iteratee(a, b, index + 1);
  } else if (result > 0) {
    return 1;
  } else if (result < 0) {
    return -1;
  } else {
    return 0;
  }
}

# counting_sort

计数排序。取最大值和最小值,统计元素出现次数,计数累加,反向填充输出。

数组 算法 排序

算法原理

  1. 找出待排序的数组中最大和最小的元素;
  2. 统计数组中每个值为 i 的元素出现的次数,存入数组 C 的第 i 项;
  3. 对所有的计数累加(从 C 中的第一个元素开始,每一项和前一项相加);
  4. 反向填充目标数组:将每个元素 i 放在新数组的第 C(i)项,每放一个元素就将 C(i)减去 1。

添加版本

0.0.1

语法

counting_sort(array, iteratee(element, index, array));

参数

  • array(Array): 需要处理的数组。
  • iteratee(element, index, array)(*): 每次迭代调用的函数。
    • a(*): 第一个用于比较的元素。
    • b(*): 第二个用于比较的元素。

返回值

(Array): 排序后的数组。

示例

@langnang/js-func/test/counting_sort.tsx (opens new window)

import { counting_sort } from '../main'

describe("counting_sort", () => {
  it("main", () => {
    const array = [1, 5, 3, 6, 4, 8, 2, 9, 7];

    expect(counting_sort(array)).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9])
  });
})

实现

  • Langnang.counting_sort

@langnang/js-func/src/counting_sort.ts (opens new window)

/**
 * @name counting_sort
 * @description 计数排序。取最大值和最小值,统计元素出现次数,计数累加,反向填充输出。
 * @category Array 数组
 * @category Algorithm 算法
 * @category Sorting 排序
 * @tip 算法原理 tip 1. 找出待排序的数组中最大和最小的元素;\n2. 统计数组中每个值为 i 的元素出现的次数,存入数组 C 的第 i 项;\n3. 对所有的计数累加(从 C 中的第一个元素开始,每一项和前一项相加);\n4. 反向填充目标数组:将每个元素 i 放在新数组的第 C(i)项,每放一个元素就将 C(i)减去 1。\n
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} iteratee(element, index, array) 每次迭代调用的函数。
 * * @param {*} a 第一个用于比较的元素。
 * * @param {*} b 第二个用于比较的元素。
 * @returns {Array} 排序后的数组。
 */
export const counting_sort = (array: any[]): any[] => {
  let min = Math.min(...array);
  let max = Math.max(...array);
  let B = Array();
  let countArray = Array();
  for (let i = 0; i < array.length; i++) {
    countArray[array[i]] = countArray[array[i]] ? countArray[array[i]] + 1 : 1;
  }
  for (var j = min; j < max; j++) {
    countArray[j + 1] = (countArray[j + 1] || 0) + (countArray[j] || 0);
  }
  for (var k = array.length - 1; k >= 0; k--) {
    B[countArray[array[k]] - 1] = array[k];
    countArray[array[k]]--;
  }
  return B;
}

# factorial

阶乘。一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且0的阶乘为1。

算术

添加版本

0.0.1

语法

factorial(num);

参数

  • num(Number): 需要计算的数值

返回值

(Number): 计算的结果

示例

@langnang/js-func/test/factorial.tsx (opens new window)

import { factorial } from '../main'

describe("factorial", () => {
  it("main", () => {
    expect(factorial(0)).toEqual(1);
    expect(factorial(1)).toEqual(1);
    expect(factorial(2)).toEqual(2);
    expect(factorial(3)).toEqual(6);
    expect(factorial(5)).toEqual(120);
    expect(factorial(7)).toEqual(5040);
    expect(factorial(10)).toEqual(3628800);
  });
})

实现

  • Langnang.factorial

@langnang/js-func/src/factorial.ts (opens new window)

/**
 * @name factorial
 * @description 阶乘。一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且0的阶乘为1。
 * @category Math 算术
 * @since 0.0.1
 * @param {Number} num 需要计算的数值
 * @returns {Number} 计算的结果
 */
export const factorial = (num: number): number => num > 1 ? num * factorial(num - 1) : 1

# gcd

欧几里得算法。计算两个非负整数的最大公约数。

算术

添加版本

0.0.1

语法

gcd(a, b);

参数

  • a(Number): 第一个非负整数
  • b(Number): 第二个非负整数

返回值

(Number): 最大公约数

示例

@langnang/js-func/test/gcd.tsx (opens new window)

import { gcd } from '../main'

describe("gcd", () => {
  it("main", () => {
    expect(gcd(1997, 615)).toEqual(1);
    expect(gcd(1232, 573)).toEqual(1);
    expect(gcd(6, 9)).toEqual(3);
  });
})

实现

  • Langnang.gcd

@langnang/js-func/src/gcd.ts (opens new window)

/**
 * @name gcd
 * @description 欧几里得算法。计算两个非负整数的最大公约数。
 * @category Math 算术
 * @since 0.0.1
 * @param {Number} a 第一个非负整数
 * @param {Number} b 第二个非负整数
 * @returns {Number} 最大公约数
 */
export const gcd = (a: number, b: number): number => {
  const gcd_a = Math.abs(a);
  const gcd_b = Math.abs(b);
  return (gcd_b === 0) ? gcd_a : gcd(gcd_b, gcd_a % gcd_b);
}

# heap_sort

堆排序。构建待排序序列成大项堆,交换堆顶元素与最后一个元素,调整新堆为大项堆。

数组 算法 排序

算法原理

  1. 将初始待排序关键字序列(R1,R2….Rn)构建成大顶堆,此堆为初始的无序区;
  2. 将堆顶元素 R[1]与最后一个元素 R[n]交换,此时得到新的无序区(R1,R2,……Rn-1)和新的有序区(Rn),且满足 R[1,2…n-1]<=R[n];
  3. 由于交换后新的堆顶 R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,……Rn-1)调整为新堆,然后再次将 R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2….Rn-2)和新的有序区 (Rn-1,Rn)。不断重复此过程直到有序区的元素个数为 n-1,则整个排序过程完成。

添加版本

0.0.1

语法

heap_sort(array, iteratee(element, index, array));

参数

  • array(Array): 需要处理的数组。
  • iteratee(element, index, array)(*): 每次迭代调用的函数。
    • a(*): 第一个用于比较的元素。
    • b(*): 第二个用于比较的元素。

返回值

(Array): 排序后的数组。

示例

@langnang/js-func/test/heap_sort.tsx (opens new window)

import { heap_sort } from '../main'

describe("heap_sort", () => {
  it("main", () => {
    const array = [1, 5, 3, 6, 4, 8, 2, 9, 7];

    expect(heap_sort(array)).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9])
  });
})

实现

  • Langnang.heap_sort

@langnang/js-func/src/heap_sort.ts (opens new window)

/**
 * @name heap_sort
 * @description 堆排序。构建待排序序列成大项堆,交换堆顶元素与最后一个元素,调整新堆为大项堆。
 * @category Array 数组
 * @category Algorithm 算法
 * @category Sorting 排序
 * @tip 算法原理 tip 1. 将初始待排序关键字序列(R1,R2….Rn)构建成大顶堆,此堆为初始的无序区;\n2. 将堆顶元素 R[1]与最后一个元素 R[n]交换,此时得到新的无序区(R1,R2,……Rn-1)和新的有序区(Rn),且满足 R[1,2…n-1]<=R[n];\n3. 由于交换后新的堆顶 R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,……Rn-1)调整为新堆,然后再次将 R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2….Rn-2)和新的有序区 (Rn-1,Rn)。不断重复此过程直到有序区的元素个数为 n-1,则整个排序过程完成。\n
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} iteratee(element, index, array) 每次迭代调用的函数。
 * * @param {*} a 第一个用于比较的元素。
 * * @param {*} b 第二个用于比较的元素。
 * @returns {Array} 排序后的数组。
 */
export const heap_sort = (array: any[]) => {
  buildMaxHeap(array);
  for (var i = array.length - 1; i > 0; i--) {
    // 堆顶元素与最后一项元素交换位置
    [array[0], array[i]] = [array[i], array[0]];
    // 调整新堆
    maxHeapify(array, 0, i);
  }
  return array;

}

function maxHeapify(array: any[], index: number, heapSize: number) {
  var iMax,
    iLeft,
    iRight;
  while (true) {
    iMax = index;
    iLeft = 2 * index + 1;
    iRight = 2 * (index + 1);
    // 如果有左子树,且左子树大于父节点,则将最大指针指向左子树
    if (iLeft < heapSize && array[index] < array[iLeft]) {
      iMax = iLeft;
    }
    // 如果有右子树,且右子树大于父节点,则将最大指针指向右子树
    if (iRight < heapSize && array[iMax] < array[iRight]) {
      iMax = iRight;
    }
    // 如果父节点不是最大值,则将父节点与最大值交换,并且递归调整与父节点交换的位置
    if (iMax != index) {
      [array[iMax], array[index]] = [array[index], array[iMax]];
      index = iMax;
    } else {
      break;
    }
  }
}

function buildMaxHeap(array: any[]) {
  // 从最后一个非叶子节点开始向上构造最大堆
  for (let i = Math.floor(array.length / 2) - 1; i >= 0; i--) {
    maxHeapify(array, i, array.length);
  }
}

# hex_to_rgba

hex十六进制颜色转rgb颜色

添加版本

0.0.2

语法

hex_to_rgba(hex, [opacity = 1]);

参数

  • hex(String): 需要转换的十六进制颜色
  • [opacity = 1](Number): 色彩透明度

返回值

(string): 转换后的颜色

实现

  • Langnang.hex_to_rgba

@langnang/js-func/src/hex_to_rgba.ts (opens new window)

/**
 * @name hex_to_rgba
 * @description hex十六进制颜色转rgb颜色
 * @since 0.0.2
 * @param {String} hex 需要转换的十六进制颜色
 * @param {Number} [opacity = 1] 色彩透明度
 * @returns {string} 转换后的颜色
 */
export const hex_to_rgba = (hex: string, opacity: number = 1): string =>
  "rgba(" +
  parseInt("0x" + hex.slice(1, 3)) +
  "," +
  parseInt("0x" + hex.slice(3, 5)) +
  "," +
  parseInt("0x" + hex.slice(5, 7)) +
  "," +
  opacity +
  ")";

# insertion_sort

插入排序。默认第一个元素为已排序,取未排序部分第一个元素,从后向前进行比较交换位置。

数组 算法 排序

算法原理

  1. 从第一个元素开始,该元素可以认为已经被排序;
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描;
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置;
  4. 重复步骤 3,直到找到已排序的元素小于或者等于新元素的位置;
  5. 将新元素插入到该位置后;
  6. 重复步骤 2~5。

添加版本

0.0.1

语法

insertion_sort(array, iteratee(element, index, array));

参数

  • array(Array): 需要处理的数组。
  • iteratee(element, index, array)(*): 每次迭代调用的函数。
    • a(*): 第一个用于比较的元素。
    • b(*): 第二个用于比较的元素。

返回值

(Array): 排序后的数组。

示例

@langnang/js-func/test/insertion_sort.tsx (opens new window)

import { insertion_sort } from '../main'

describe("insertion_sort", () => {
  it("main", () => {
    const array = [1, 5, 3, 6, 4, 8, 2, 9, 7];

    expect(insertion_sort(array)).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9])
  });
})

实现

  • Langnang.insertion_sort

@langnang/js-func/src/insertion_sort.ts (opens new window)

/**
 * @name insertion_sort
 * @description 插入排序。默认第一个元素为已排序,取未排序部分第一个元素,从后向前进行比较交换位置。
 * @category Array 数组
 * @category Algorithm 算法
 * @category Sorting 排序
 * @tip 算法原理 tip 1. 从第一个元素开始,该元素可以认为已经被排序;\n2. 取出下一个元素,在已经排序的元素序列中从后向前扫描;\n3. 如果该元素(已排序)大于新元素,将该元素移到下一位置;\n4. 重复步骤 3,直到找到已排序的元素小于或者等于新元素的位置;\n5. 将新元素插入到该位置后;\n6. 重复步骤 2~5。\n
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} iteratee(element, index, array) 每次迭代调用的函数。
 * * @param {*} a 第一个用于比较的元素。
 * * @param {*} b 第二个用于比较的元素。
 * @returns {Array} 排序后的数组。
 */
export const insertion_sort = (array: any[]) => {
  const insertion = (array: any[], index: number) => {
    // 从后向前遍历
    for (let i = index - 1; i >= 0; i--) {
      // 如果后一个元素小于前一个元素
      if (array[i] > array[i + 1]) {
        // 交换元素位置
        [array[i], array[i + 1]] = [array[i + 1], array[i]];
      } else {
        // 停止循环
        break;
      }
    }
  }
  for (let i = 1; i < array.length; i++) {
    insertion(array, i);
  }
  return array;
}

# is_array

检测对象是否为数组类型

添加版本

0.0.1

语法

is_array(object);

参数

  • object(*): 需要检测的对象

返回值

(Boolean): 检测结果

示例

@langnang/js-func/test/is_array.tsx (opens new window)

import { is_array } from "../main";

describe("is_array", () => {
  it('main', function () {
    expect(is_array(null)).toEqual(false);
    expect(is_array(undefined)).toEqual(false);
    expect(is_array([])).toEqual(true);
    expect(is_array({})).toEqual(false);
    expect(is_array("")).toEqual(false);
    expect(is_array(0)).toEqual(false);
    expect(is_array(NaN)).toEqual(false);
    expect(is_array(true)).toEqual(false);
    expect(is_array(new Date())).toEqual(false);
    expect(is_array(new RegExp(''))).toEqual(false);
  });
})

实现

  • Langnang.is_array

@langnang/js-func/src/is_array.ts (opens new window)

/**
 * @name is_array
 * @description 检测对象是否为数组类型
 * @since 0.0.1
 * @param {*} object 需要检测的对象
 * @returns {Boolean} 检测结果
 */
export const is_array = (object: any): boolean =>
  Object.prototype.toString.call(object) === "[object Array]";

# is_boolean

检测对象是否为布尔类型

添加版本

0.0.1

语法

is_boolean(object);

参数

  • object(*): 需要检测的对象

返回值

(Boolean): 检测结果

示例

@langnang/js-func/test/is_boolean.tsx (opens new window)

import { is_boolean } from '../main'

describe("is_boolean", () => {
  it("main", () => {
    expect(is_boolean(null)).toEqual(false);
    expect(is_boolean(undefined)).toEqual(false);
    expect(is_boolean([])).toEqual(false);
    expect(is_boolean({})).toEqual(false);
    expect(is_boolean("")).toEqual(false);
    expect(is_boolean(0)).toEqual(false);
    expect(is_boolean(NaN)).toEqual(false);
    expect(is_boolean(true)).toEqual(true);
    expect(is_boolean(new Date())).toEqual(false);
    expect(is_boolean(new RegExp(''))).toEqual(false);
  });
})

实现

  • Langnang.is_boolean

@langnang/js-func/src/is_boolean.ts (opens new window)

/**
 * @name is_boolean
 * @description 检测对象是否为布尔类型
 * @since 0.0.1
 * @param {*} object 需要检测的对象
 * @returns {Boolean} 检测结果
 */
export const is_boolean = (object: any) =>
  Object.prototype.toString.call(object) === "[object Boolean]";

# is_date

检测对象是否为 Date 类型

添加版本

0.0.1

语法

is_date(object);

参数

  • object(*): 需要检测的对象

返回值

(Boolean): 检测结果

示例

@langnang/js-func/test/is_date.tsx (opens new window)

import { is_date } from '../main'

describe("is_date", () => {
  it("main", () => {
    expect(is_date(null)).toEqual(false);
    expect(is_date(undefined)).toEqual(false);
    expect(is_date([])).toEqual(false);
    expect(is_date({})).toEqual(false);
    expect(is_date("")).toEqual(false);
    expect(is_date(0)).toEqual(false);
    expect(is_date(NaN)).toEqual(false);
    expect(is_date(true)).toEqual(false);
    expect(is_date(new Date())).toEqual(true);
    expect(is_date(new RegExp(''))).toEqual(false);
  });
})

实现

  • Langnang.is_date

@langnang/js-func/src/is_date.ts (opens new window)

/**
 * @name is_date
 * @description 检测对象是否为 `Date` 类型
 * @since 0.0.1
 * @param {*} object 需要检测的对象
 * @returns {Boolean} 检测结果
 */
export const is_date = (object: any): boolean =>
  Object.prototype.toString.call(object) === "[object Date]";

# is_defined

检测对象是否已定义

添加版本

0.0.1

语法

is_defined(object);

参数

  • object(*): 需要检测的对象

返回值

(Boolean): 检测结果

示例

@langnang/js-func/test/is_defined.tsx (opens new window)

import { is_defined } from '../main'

describe("is_defined", () => {
  it("main", () => {
    expect(is_defined(null)).toEqual(false);
    expect(is_defined(undefined)).toEqual(false);
    expect(is_defined([])).toEqual(true);
    expect(is_defined({})).toEqual(true);
    expect(is_defined("")).toEqual(true);
    expect(is_defined(0)).toEqual(true);
    expect(is_defined(NaN)).toEqual(true);
    expect(is_defined(true)).toEqual(true);
    expect(is_defined(new Date())).toEqual(true);
    expect(is_defined(new RegExp(''))).toEqual(true);
  });
})

实现

  • Langnang.is_defined

@langnang/js-func/src/is_defined.ts (opens new window)

import { is_null } from "./is_null";
import { is_undefined } from "./is_undefined";

/**
 * @name is_defined
 * @description 检测对象是否已定义
 * @since 0.0.1
 * @param {*} object 需要检测的对象
 * @returns {Boolean} 检测结果
 */
export const is_defined = (object: any): boolean => !is_null(object) && !is_undefined(object)

# is_dom

检测对象是否 DOM

添加版本

0.0.1

语法

is_dom(object);

参数

  • object(*):

返回值

(Boolean): 检测结果

实现

  • Langnang.is_dom

@langnang/js-func/src/is_dom.ts (opens new window)

import { object_type } from "./object_type";

/**
 * @name is_dom
 * @description 检测对象是否 `DOM`
 * @since 0.0.1
 * @param {*} object
 * @returns {Boolean} 检测结果
 * TODO jest
 */
export const is_dom = (object: any) =>
  object_type(HTMLElement) === "object"
    ? object instanceof HTMLElement
    : object &&
    object_type(object) === "object" &&
    object.nodetypeOf === 1 &&
    object_type(object.nodeName) === "string";

# is_empty

检测对象是否为空

添加版本

0.0.1

语法

is_empty(object);

参数

  • object(*): 需要检测的对象

返回值

(Boolean): 检测结果

示例

@langnang/js-func/test/is_empty.tsx (opens new window)

import { is_empty } from '../main'

describe("is_empty", () => {
  it("main", () => {
    expect(is_empty(null)).toEqual(true);
    expect(is_empty(undefined)).toEqual(true);
    expect(is_empty([])).toEqual(false);
    expect(is_empty({})).toEqual(false);
    expect(is_empty("")).toEqual(true);
    expect(is_empty(0)).toEqual(false);
    expect(is_empty(NaN)).toEqual(false);
    expect(is_empty(true)).toEqual(false);
    expect(is_empty(new Date())).toEqual(false);
    expect(is_empty(new RegExp(''))).toEqual(false);
  });
})

实现

  • Langnang.is_empty

@langnang/js-func/src/is_empty.ts (opens new window)

import { is_null } from "./is_null";
import { is_string } from "./is_string";
import { is_undefined } from "./is_undefined";

/**
 * @name is_empty
 * @description 检测对象是否为空
 * @since 0.0.1
 * @param {*} object 需要检测的对象
 * @returns {Boolean} 检测结果
 */
export const is_empty = (object: any) =>
  is_null(object)
  || is_undefined(object)
  || (is_string(object) && object == '')

# is_false

检测对象是否为 false

添加版本

0.0.1

语法

is_false(object);

参数

  • object(*): 需要检测的对象

返回值

(Boolean): 检测结果

示例

@langnang/js-func/test/is_false.tsx (opens new window)

import { is_false } from '../main'

describe("is_false", () => {
  it("main", () => {
    expect(is_false(null)).toEqual(false);
    expect(is_false(undefined)).toEqual(false);
    expect(is_false([])).toEqual(false);
    expect(is_false({})).toEqual(false);
    expect(is_false("")).toEqual(false);
    expect(is_false(0)).toEqual(false);
    expect(is_false(NaN)).toEqual(false);
    expect(is_false(true)).toEqual(false);
    expect(is_false(false)).toEqual(true);
    expect(is_false(new Date())).toEqual(false);
    expect(is_false(new RegExp(''))).toEqual(false);
  });
})

实现

  • Langnang.is_false

@langnang/js-func/src/is_false.ts (opens new window)

import { is_boolean } from "./is_boolean";

/**
 * @name is_false
 * @description 检测对象是否为 `false`
 * @since 0.0.1
 * @param {*} object 需要检测的对象
 * @returns {Boolean} 检测结果
 */
export const is_false = (object: any): boolean => is_boolean(object) && object === false;

# is_function

检测对象是否为函数类型

添加版本

0.0.1

语法

is_function(object);

参数

  • object(*): 需要检测的对象

返回值

(Boolean): 检测结果

示例

@langnang/js-func/test/is_function.tsx (opens new window)

import { is_function } from '../main'

describe("is_function", () => {
  it("main", () => {
    expect(is_function(null)).toEqual(false);
    expect(is_function(undefined)).toEqual(false);
    expect(is_function([])).toEqual(false);
    expect(is_function({})).toEqual(false);
    expect(is_function("")).toEqual(false);
    expect(is_function(0)).toEqual(false);
    expect(is_function(NaN)).toEqual(false);
    expect(is_function(true)).toEqual(false);
    expect(is_function(new Date())).toEqual(false);
    expect(is_function(new RegExp(''))).toEqual(false);
    expect(is_function(() => { })).toEqual(true);
  });
})

实现

  • Langnang.is_function

@langnang/js-func/src/is_function.ts (opens new window)

/**
 * @name is_function
 * @description 检测对象是否为函数类型
 * @since 0.0.1
 * @param {*} object 需要检测的对象
 * @returns {Boolean} 检测结果
 */
export const is_function = (object: any) =>
  Object.prototype.toString.call(object) === "[object Function]";

# is_null

检测对象是否为 Null

添加版本

0.0.1

语法

is_null(object);

参数

  • object(*): 需要检测的对象

返回值

(Boolean): 检测结果

示例

@langnang/js-func/test/is_null.tsx (opens new window)

import { is_null } from '../main'

describe("is_null", () => {
  it("main", () => {
    expect(is_null(null)).toEqual(true);
    expect(is_null(undefined)).toEqual(false);
    expect(is_null([])).toEqual(false);
    expect(is_null({})).toEqual(false);
    expect(is_null("")).toEqual(false);
    expect(is_null(0)).toEqual(false);
    expect(is_null(NaN)).toEqual(false);
    expect(is_null(true)).toEqual(false);
    expect(is_null(new Date())).toEqual(false);
    expect(is_null(new RegExp(''))).toEqual(false);
  });
})

实现

  • Langnang.is_null

@langnang/js-func/src/is_null.ts (opens new window)

/**
 * @name is_null
 * @description 检测对象是否为 `Null`
 * @since 0.0.1
 * @param {*} object 需要检测的对象
 * @returns {Boolean} 检测结果
 */
export const is_null = (object: any) =>
  Object.prototype.toString.call(object) === "[object Null]";

# is_number

检测对象是否为数值类型

添加版本

0.0.1

语法

is_number(object);

参数

  • object(*): 需要检测的对象

返回值

(Boolean): 检测结果

示例

@langnang/js-func/test/is_number.tsx (opens new window)

import { is_number } from '../main'

describe("is_number", () => {
  it("main", () => {
    expect(is_number(null)).toEqual(false);
    expect(is_number(undefined)).toEqual(false);
    expect(is_number([])).toEqual(false);
    expect(is_number({})).toEqual(false);
    expect(is_number("")).toEqual(false);
    expect(is_number(0)).toEqual(true);
    expect(is_number(NaN)).toEqual(true);
    expect(is_number(true)).toEqual(false);
    expect(is_number(new Date())).toEqual(false);
    expect(is_number(new RegExp(''))).toEqual(false);
  });
})

实现

  • Langnang.is_number

@langnang/js-func/src/is_number.ts (opens new window)

/**
 * @name is_number
 * @description 检测对象是否为数值类型
 * @since 0.0.1
 * @param {*} object 需要检测的对象
 * @returns {Boolean} 检测结果
 */
export const is_number = (object: any): boolean => Object.prototype.toString.call(object) === "[object Number]" 

# is_object

检测对象是否为对象类型

添加版本

0.0.1

语法

is_object(object);

参数

  • object(*): 需要检测的对象

返回值

(Boolean): 检测结果

示例

@langnang/js-func/test/is_object.tsx (opens new window)

import { is_object } from '../main'

describe("is_object", () => {
  it("main", () => {
    expect(is_object(null)).toEqual(false);
    expect(is_object(undefined)).toEqual(false);
    expect(is_object([])).toEqual(false);
    expect(is_object({})).toEqual(true);
    expect(is_object("")).toEqual(false);
    expect(is_object(0)).toEqual(false);
    expect(is_object(NaN)).toEqual(false);
    expect(is_object(true)).toEqual(false);
    expect(is_object(new Date())).toEqual(false);
    expect(is_object(new RegExp(''))).toEqual(false);
  });
})

实现

  • Langnang.is_object

@langnang/js-func/src/is_object.ts (opens new window)

/**
 * @name is_object
 * @description 检测对象是否为对象类型
 * @since 0.0.1
 * @param {*} object 需要检测的对象
 * @returns {Boolean} 检测结果
 */
export const is_object = (object: any) =>
  Object.prototype.toString.call(object) === "[object Object]";

# is_primitive

检测对象是否是原始数据类型

添加版本

0.0.1

语法

is_primitive(object);

参数

  • object(*): 需要检测的对象

返回值

(Boolean): 检测结果

示例

@langnang/js-func/test/is_primitive.tsx (opens new window)

import { is_primitive } from '../main'

describe("is_primitive", () => {
  it("main", () => {
    expect(is_primitive(null)).toEqual(false);
    expect(is_primitive(undefined)).toEqual(false);
    expect(is_primitive([])).toEqual(false);
    expect(is_primitive({})).toEqual(false);
    expect(is_primitive("")).toEqual(true);
    expect(is_primitive(0)).toEqual(true);
    expect(is_primitive(NaN)).toEqual(true);
    expect(is_primitive(true)).toEqual(true);
    expect(is_primitive(new Date())).toEqual(false);
    expect(is_primitive(new RegExp(''))).toEqual(false);
  });
})

实现

  • Langnang.is_primitive

@langnang/js-func/src/is_primitive.ts (opens new window)

/**
 * @name is_primitive
 * @description 检测对象是否是原始数据类型
 * @since 0.0.1
 * @param {*} object 需要检测的对象
 * @returns {Boolean} 检测结果
 */
export const is_primitive = (object: any) =>
  typeof object === "string" ||
  typeof object === "number" ||
  typeof object === "symbol" ||
  typeof object === "boolean";

# is_regexp

检测对象是否为 RegExp 类型

添加版本

0.0.1

语法

is_regexp(object);

参数

  • object(*): 需要检测的对象

返回值

(Boolean): 检测结果

示例

@langnang/js-func/test/is_regexp.tsx (opens new window)

import { is_regexp } from '../main'

describe("is_regexp", () => {
  it("main", () => {
    expect(is_regexp(null)).toEqual(false);
    expect(is_regexp(undefined)).toEqual(false);
    expect(is_regexp([])).toEqual(false);
    expect(is_regexp({})).toEqual(false);
    expect(is_regexp("")).toEqual(false);
    expect(is_regexp(0)).toEqual(false);
    expect(is_regexp(NaN)).toEqual(false);
    expect(is_regexp(true)).toEqual(false);
    expect(is_regexp(new Date())).toEqual(false);
    expect(is_regexp(new RegExp(''))).toEqual(true);
  });
})

实现

  • Langnang.is_regexp

@langnang/js-func/src/is_regexp.ts (opens new window)

/**
 * @name is_regexp
 * @description 检测对象是否为 `RegExp` 类型
 * @since 0.0.1
 * @param {*} object 需要检测的对象
 * @returns {Boolean} 检测结果
 */
export const is_regexp = (object: any) =>
  Object.prototype.toString.call(object) === "[object RegExp]";

# is_string

检测对象是否为字符串类型

添加版本

0.0.1

语法

is_string(object);

参数

  • object(*): 需要检测的对象

返回值

(Boolean): 检测结果

示例

@langnang/js-func/test/is_string.tsx (opens new window)

import { is_string } from "../main";

describe("is_string", () => {
  it('main', function () {
    expect(is_string(null)).toEqual(false);
    expect(is_string(undefined)).toEqual(false);
    expect(is_string([])).toEqual(false);
    expect(is_string({})).toEqual(false);
    expect(is_string("")).toEqual(true);
    expect(is_string(0)).toEqual(false);
    expect(is_string(NaN)).toEqual(false);
    expect(is_string(true)).toEqual(false);
    expect(is_string(new Date())).toEqual(false);
    expect(is_string(new RegExp(''))).toEqual(false);
  });
})

实现

  • Langnang.is_string

@langnang/js-func/src/is_string.ts (opens new window)

/**
 * @name is_string
 * @description 检测对象是否为字符串类型
 * @since 0.0.1
 * @param {*} object 需要检测的对象
 * @returns {Boolean} 检测结果
 */
export const is_string = (object: any): boolean =>
  Object.prototype.toString.call(object) === "[object String]";

# is_symbol

检测对象是否为 Symbol

添加版本

0.0.1

语法

is_symbol(object);

参数

  • object(*): 需要检测的对象

返回值

(Boolean): 检测结果

示例

@langnang/js-func/test/is_symbol.tsx (opens new window)

import { is_symbol } from '../main'

describe("is_symbol", () => {
  it("main", () => {
    expect(is_symbol(null)).toEqual(false);
    expect(is_symbol(undefined)).toEqual(false);
    expect(is_symbol([])).toEqual(false);
    expect(is_symbol({})).toEqual(false);
    expect(is_symbol("")).toEqual(false);
    expect(is_symbol(0)).toEqual(false);
    expect(is_symbol(NaN)).toEqual(false);
    expect(is_symbol(true)).toEqual(false);
    expect(is_symbol(Date())).toEqual(false);
    expect(is_symbol(RegExp(''))).toEqual(false);
    expect(is_symbol(Symbol())).toEqual(true);
  });
})

实现

  • Langnang.is_symbol

@langnang/js-func/src/is_symbol.ts (opens new window)

/**
 * @name is_symbol
 * @description 检测对象是否为 `Symbol`
 * @since 0.0.1
 * @param {*} object 需要检测的对象
 * @returns {Boolean} 检测结果
 */
export const is_symbol = (object: any): boolean =>
  Object.prototype.toString.call(object) === "[object Symbol]";

# is_true

检测对象是否为 true

添加版本

0.0.1

语法

is_true(object);

参数

  • object(*): 需要检测的对象

返回值

(Boolean): 检测结果

示例

@langnang/js-func/test/is_true.tsx (opens new window)

import { is_true } from '../main'

describe("is_true", () => {
  it("main", () => {
    expect(is_true(null)).toEqual(false);
    expect(is_true(undefined)).toEqual(false);
    expect(is_true([])).toEqual(false);
    expect(is_true({})).toEqual(false);
    expect(is_true("")).toEqual(false);
    expect(is_true(0)).toEqual(false);
    expect(is_true(NaN)).toEqual(false);
    expect(is_true(true)).toEqual(true);
    expect(is_true(false)).toEqual(false);
    expect(is_true(new Date())).toEqual(false);
    expect(is_true(new RegExp(''))).toEqual(false);
  });
})

实现

  • Langnang.is_true

@langnang/js-func/src/is_true.ts (opens new window)

import { is_boolean } from "./is_boolean";

/**
 * @name is_true
 * @description 检测对象是否为 `true`
 * @since 0.0.1
 * @param {*} object 需要检测的对象
 * @returns {Boolean} 检测结果
 */
export const is_true = (object: any) => is_boolean(object) && object === true;

# is_undefined

检测对象是否为 Undefined

添加版本

0.0.1

语法

is_undefined(object);

参数

  • object(*): 需要检测的对象

返回值

(Boolean): 检测结果

示例

@langnang/js-func/test/is_undefined.tsx (opens new window)

import { is_undefined } from '../main'

describe("is_undefined", () => {
  it("main", () => {
    expect(is_undefined(null)).toEqual(false);
    expect(is_undefined(undefined)).toEqual(true);
    expect(is_undefined([])).toEqual(false);
    expect(is_undefined({})).toEqual(false);
    expect(is_undefined("")).toEqual(false);
    expect(is_undefined(0)).toEqual(false);
    expect(is_undefined(NaN)).toEqual(false);
    expect(is_undefined(true)).toEqual(false);
    expect(is_undefined(new Date())).toEqual(false);
    expect(is_undefined(new RegExp(''))).toEqual(false);
  });
})

实现

  • Langnang.is_undefined

@langnang/js-func/src/is_undefined.ts (opens new window)

/**
 * @name is_undefined
 * @description 检测对象是否为 `Undefined`
 * @since 0.0.1
 * @param {*} object 需要检测的对象
 * @returns {Boolean} 检测结果
 */
export const is_undefined = (object: any) =>
  Object.prototype.toString.call(object) === "[object Undefined]";

# max

计算最大值

undefined

添加版本

0.0.2

语法

max(nums);

参数

  • nums(...Number): 需要计算的数值

实现

  • Langnang.max

@langnang/js-func/src/max.ts (opens new window)

import { array_reduce } from "./array_reduce";

/**
 * @name max
 * @description 计算最大值
 * @category Math
 * @since 0.0.2
 * @param {...Number} nums 需要计算的数值
 * @returns{Number} 计算的结果
 */
export const max = (...nums: number[]): number => array_reduce(nums, (acc: number, val: number) => (acc > val ? acc : val), 0);

# merge_sort

归并排序。递归分割序列,比较合并已排序序列。

数组 算法 排序

算法原理

  1. 把长度为 n 的输入序列分成两个长度为 n/2 的子序列;
  2. 对这两个子序列分别采用归并排序;
  3. 将两个排序好的子序列合并成一个最终的排序序列。

添加版本

0.0.1

语法

merge_sort(array, iteratee(element, index, array));

参数

  • array(Array): 需要处理的数组。
  • iteratee(element, index, array)(*): 每次迭代调用的函数。
    • a(*): 第一个用于比较的元素。
    • b(*): 第二个用于比较的元素。

返回值

(Array): 排序后的数组。

示例

@langnang/js-func/test/merge_sort.tsx (opens new window)

import { merge_sort } from '../main'

describe("merge_sort", () => {
  it("main", () => {
    const array = [1, 5, 3, 6, 4, 8, 2, 9, 7];

    expect(merge_sort(array)).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9])
  });
})

实现

  • Langnang.merge_sort

@langnang/js-func/src/merge_sort.ts (opens new window)

/**
 * @name merge_sort
 * @description 归并排序。递归分割序列,比较合并已排序序列。
 * @category Array 数组
 * @category Algorithm 算法
 * @category Sorting 排序
 * @tip 算法原理 tip 1. 把长度为 n 的输入序列分成两个长度为 n/2 的子序列;\n2. 对这两个子序列分别采用归并排序;\n3. 将两个排序好的子序列合并成一个最终的排序序列。\n
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} iteratee(element, index, array) 每次迭代调用的函数。
 * * @param {*} a 第一个用于比较的元素。
 * * @param {*} b 第二个用于比较的元素。
 * @returns {Array} 排序后的数组。
 */
export const merge_sort = (array: any[]): any[] => {
  if (array.length < 2) return array;
  const merge = (left: any[], right: any[]) => {
    let result = [];
    while (left.length > 0 && right.length > 0) {
      if (left[0] <= right[0]) {
        result.push(left.shift());
      } else {
        result.push(right.shift());
      }
    }
    while (left.length > 0) {
      result.push(left.shift());
    }
    while (right.length > 0) {
      result.push(right.shift());
    }
    return result;
  }
  let result: any[] = merge(merge_sort(array.slice(0, Math.floor(array.length / 2))), merge_sort(array.slice(Math.floor(array.length / 2))));
  return result;
}

# min

计算最小值

undefined

添加版本

0.0.2

语法

min(nums);

参数

  • nums(...Number): 需要计算的数值

实现

  • Langnang.min

@langnang/js-func/src/min.ts (opens new window)

import { array_reduce } from "./array_reduce";

/**
 * @name min
 * @description 计算最小值
 * @category Math
 * @since 0.0.2
 * @param {...Number} nums 需要计算的数值
 * @returns{Number} 计算的结果
 */
export const min = (...nums: number[]): number => array_reduce(nums, (acc: number, val: number) => (acc < val ? acc : val), 0);

# mobile_type

检测移动设备的终端类型

添加版本

0.0.1

语法

mobile_type();

返回值

(String): 设备的终端类型

实现

  • Langnang.mobile_type

@langnang/js-func/src/mobile_type.ts (opens new window)

// TODO jest
/**
 * @name mobile_type
 * @description 检测移动设备的终端类型
 * @since 0.0.1
 * @returns {String} 设备的终端类型
 */
export const mobile_type = () => {
  if (!window && !navigator) return undefined;
  const u = (window.navigator || navigator).userAgent
  const isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1 // g
  if (isAndroid) return 'Android';

  const isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) // ios终端
  if (isIOS) return 'IOS';


  return undefined;
}

# object_type

检测对象的数据类型

添加版本

0.0.1

语法

object_type(object);

参数

  • object(*): 需要检测的对象

返回值

(String): 对象的数据类型

示例

@langnang/js-func/test/object_type.tsx (opens new window)

import { object_type } from '../main'

describe("object_type", () => {
  it("main", () => {
    expect(object_type(null)).toEqual('null');
    expect(object_type(undefined)).toEqual('undefined');
    expect(object_type([])).toEqual('array');
    expect(object_type({})).toEqual('object');
    expect(object_type("")).toEqual('string');
    expect(object_type(0)).toEqual('number');
    expect(object_type(NaN)).toEqual('number');
    expect(object_type(true)).toEqual('boolean');
    expect(object_type(new Date())).toEqual('date');
    expect(object_type(new RegExp(''))).toEqual('regexp');
  });
})

实现

  • Langnang.object_type

@langnang/js-func/src/object_type.ts (opens new window)

/**
 * @name object_type
 * @description 检测对象的数据类型
 * @since 0.0.1
 * @param {*} object 需要检测的对象
 * @returns {String} 对象的数据类型
 */
export const object_type = (object: any): string =>
  Object.prototype.toString
    .call(object)
    .substring(8, Object.prototype.toString.call(object).length - 1)
    .toLowerCase();

# quick_sort

快速排序。根据基准值分割序列,左侧小于,右侧大于,递归执行后合并。

数组 算法 排序

算法原理

  1. 从数列中挑出一个元素,称为 “基准”(pivot);
  2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

添加版本

0.0.1

语法

quick_sort(array, iteratee(element, index, array));

参数

  • array(Array): 需要处理的数组。
  • iteratee(element, index, array)(*): 每次迭代调用的函数。
    • a(*): 第一个用于比较的元素。
    • b(*): 第二个用于比较的元素。

返回值

(Array): 排序后的数组。

示例

@langnang/js-func/test/quick_sort.tsx (opens new window)

import { quick_sort } from '../main'

describe("quick_sort", () => {
  it("main", () => {
    const array = [1, 5, 3, 6, 4, 8, 2, 9, 7];

    expect(quick_sort(array)).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9])
  });
})

实现

  • Langnang.quick_sort

@langnang/js-func/src/quick_sort.ts (opens new window)

/**
 * @name quick_sort
 * @description 快速排序。根据基准值分割序列,左侧小于,右侧大于,递归执行后合并。
 * @category Array 数组
 * @category Algorithm 算法
 * @category Sorting 排序
 * @tip 算法原理 tip 1. 从数列中挑出一个元素,称为 “基准”(pivot);\n2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;\n3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。\n
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} iteratee(element, index, array) 每次迭代调用的函数。
 * * @param {*} a 第一个用于比较的元素。
 * * @param {*} b 第二个用于比较的元素。
 * @returns {Array} 排序后的数组。
 */
export const quick_sort = (array: any[]) => {
  // 引用传递
  let _array = array.slice(0);
  // 内存溢出
  if (_array.length <= 1) return _array;
  // 初始化基值,左侧(小于基值)数组,右侧(大于基值)数组
  let pivot: any[] = _array.splice(Math.floor(_array.length / 2), 1)[0],
    left: any[] = [],
    right: any[] = [];
  // 遍历比较每个元素值与基值,分类push至左右数组
  for (let i = 0; i < _array.length; i++) {
    _array[i] <= pivot ? left.push(_array[i]) : right.push(_array[i]);
  }
  // 递归
  let result: any[] = quick_sort(left).concat(pivot, ...quick_sort(right));
  return result;
}

# radix_sort

基数排序。取最大值及其位数,取元素的每个位组成技术序列,进行计数排序。

数组 算法 排序

算法原理

  1. 取得数组中的最大数,并取得位数;
  2. array 为原始数组,从最低位开始取每个位组成 radix 数组;
  3. 对 radix 进行计数排序(利用计数排序适用于小范围数的特点);

添加版本

0.0.1

语法

radix_sort(array, iteratee(element, index, array));

参数

  • array(Array): 需要处理的数组。
  • iteratee(element, index, array)(*): 每次迭代调用的函数。
    • a(*): 第一个用于比较的元素。
    • b(*): 第二个用于比较的元素。

返回值

(Array): 排序后的数组。

示例

@langnang/js-func/test/radix_sort.tsx (opens new window)

import { radix_sort } from '../main'

describe("radix_sort", () => {
  it("main", () => {
    const array = [1, 5, 3, 6, 4, 8, 2, 9, 7];

    expect(radix_sort(array)).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9])
  });
})

实现

  • Langnang.radix_sort

@langnang/js-func/src/radix_sort.ts (opens new window)

/**
 * @name radix_sort
 * @description 基数排序。取最大值及其位数,取元素的每个位组成技术序列,进行计数排序。
 * @category Array 数组
 * @category Algorithm 算法
 * @category Sorting 排序
 * @tip 算法原理 tip 1. 取得数组中的最大数,并取得位数;\n2. array 为原始数组,从最低位开始取每个位组成 radix 数组;\n3. 对 radix 进行计数排序(利用计数排序适用于小范围数的特点);\n
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} iteratee(element, index, array) 每次迭代调用的函数。
 * * @param {*} a 第一个用于比较的元素。
 * * @param {*} b 第二个用于比较的元素。
 * @returns {Array} 排序后的数组。
 */
export const radix_sort = (array: any[]) => {
  const maxDigit = (num: number, digit: number = 1) => {
    if (num <= -10 || num >= 10) {
      digit = maxDigit(num / 10, ++digit);
    }
    return digit;
  }
  let digit = maxDigit(Math.max(...array));
  var mod = 10;
  var dev = 1;
  var counter = [];
  for (var i = 0; i < digit; i++, dev *= 10, mod *= 10) {
    for (var j = 0; j < array.length; j++) {
      var bucket = Math.floor((array[j] % mod) / dev);
      if (counter[bucket] == null) {
        counter[bucket] = [];
      }
      counter[bucket].push(array[j]);
    }
    var pos = 0;
    for (var j = 0; j < counter.length; j++) {
      var value = null;
      if (counter[j] != null) {
        while ((value = counter[j].shift()) != null) {
          array[pos++] = value;
        }
      }
    }
  }
  return array;
}

# random

生成随机数值

添加版本

0.0.1

语法

random([max = 1], [min = 0]);

参数

  • [max = 1](Number): 随机数值最大范围,默认为1
  • [min = 0](Number): 随机数值最小范围,默认为1

返回值

(Number): 随机数值

示例

@langnang/js-func/test/random.tsx (opens new window)

import { random } from "../main";

describe("random", () => {
  it('main', function () {
    expect(random(3)).toBeGreaterThanOrEqual(0);
    expect(random(3)).toBeLessThanOrEqual(3);
  });
})

实现

  • Langnang.random

@langnang/js-func/src/random.ts (opens new window)

/**
 * @name random
 * @description 生成随机数值
 * @since 0.0.1
 * @param {Number} [max = 1] 随机数值最大范围,默认为1
 * @param {Number} [min = 0] 随机数值最小范围,默认为1
 * @returns {Number} 随机数值
 */
export const random = (max: number = 1, min: number = 0): number => Math.random() * (max - min) + min;

# random_int

生成随机整数数值

添加版本

0.0.1

语法

random_int([max = 1], [min = 0]);

参数

  • [max = 1](Number): 随机值最大范围,默认为1
  • [min = 0](Number): 随机值最小范围,默认为1

返回值

(Number): 随机整数数值

示例

@langnang/js-func/test/random_int.tsx (opens new window)

import { random_int } from "../main";

describe("random_int", () => {
  it('main', function () {
    expect(random_int(3)).toBeGreaterThanOrEqual(0);
    expect(random_int(3)).toBeLessThanOrEqual(3);
  });
})

实现

  • Langnang.random_int

@langnang/js-func/src/random_int.ts (opens new window)

import { random } from "./random";

/**
 * @name random_int
 * @description 生成随机整数数值
 * @since 0.0.1
 * @param {Number} [max = 1] 随机值最大范围,默认为1
 * @param {Number} [min = 0] 随机值最小范围,默认为1
 * @returns {Number} 随机整数数值
 */
export const random_int = (max: number = 1, min: number = 0): number => Math.floor(random(max, min));

# random_sudoku

生成随机九宫格数独

添加版本

0.0.1

语法

random_sudoku(items);

参数

  • items(Array): 九宫格元素数组

返回值

(Array): 随机九宫格数独

实现

  • Langnang.random_sudoku

@langnang/js-func/src/random_sudoku.ts (opens new window)

import { random_int } from "./random_int";
// TODO

/**
 * @name random_sudoku
 * @description 生成随机九宫格数独
 * @since 0.0.1
 * @param {Array} items 九宫格元素数组
 * @returns {Array} 随机九宫格数独
 */
export const random_sudoku = (items: any[] = [1, 2, 3, 4, 5, 6, 7, 8, 9]) => {
  let result: any[] = [];
  for (let i = 0; i < 9; i++) {
    let row = [...items];
    if (i >= 6) {
      row = row.slice(5).concat(row.slice(0)).slice(0, 9);
    } else if (i >= 3) {
      row = row.slice(7).concat(row.slice(0)).slice(0, 9);
    }
    result[i] = row.slice((i % 3) * 3).concat(row.slice(0, (i % 3) * 3));
  }
  let i = 0;
  while (i < random_int() * 10000) {
    let rc1: number = random_int(9);
    let rc2: number = rc1;
    switch (rc1 % 3) {
      case 0:
        rc2 = Math.random() > 0.5 ? rc1 + 1 : rc1 + 2;
        break;
      case 1:
        rc2 = Math.random() > 0.5 ? rc1 - 1 : rc1 + 1;
        break;
      case 2:
        rc2 = Math.random() > 0.5 ? rc1 - 1 : rc1 - 2;
        break;
      default:
        break;
    }
    if (Math.random() > 0.5) {
      [result[rc1], result[rc2]] = [result[rc2], result[rc1]];
    } else {
      for (let i = 0; i < 9; i++) {
        [result[i][rc1], result[i][rc2]] = [result[i][rc2], result[i][rc1]];
      }
    }
    i++;
  }
  return result;
};

# rgb_to_hex

rgb颜色转hex十六进制颜色

添加版本

0.0.2

语法

rgb_to_hex(r, g, b);

参数

  • r(Number):
  • g(Number):
  • b(Number):

返回值

(string): 转换后的十六进制颜色

实现

  • Langnang.rgb_to_hex

@langnang/js-func/src/rgb_to_hex.ts (opens new window)

/**
 * @name rgb_to_hex
 * @description rgb颜色转hex十六进制颜色
 * @since 0.0.2
 * @param {Number} r
 * @param {Number} g
 * @param {Number} b
 * @returns {string} 转换后的十六进制颜色
 */
export const rgb_to_hex = (r: number, g: number, b: number) =>
  "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);

# selection_sort

选择排序。重复遍历未排序部分,将最小元素移至已排序末尾。

数组 算法 排序

算法原理

  1. 初始状态:无序区为 R[1..n],有序区为空;
  2. 第 i 趟排序(i=1,2,3…n-1)开始时,当前有序区和无序区分别为 R[1..i-1]和 R(i..n)。该趟排序从当前无序区中-选出关键字最小的记录 R[k],将它与无序区的第 1 个记录 R 交换,使 R[1..i]和 R[i+1..n)分别变为记录个数增加 1 个的新有序区和记录个数减少 1 个的新无序区;
  3. n-1 趟结束,数组有序化了。

添加版本

0.0.1

语法

selection_sort(array, iteratee(element, index, array));

参数

  • array(Array): 需要处理的数组。
  • iteratee(element, index, array)(*): 每次迭代调用的函数。
    • a(*): 第一个用于比较的元素。
    • b(*): 第二个用于比较的元素。

返回值

(Array): 排序后的数组。

示例

@langnang/js-func/test/selection_sort.tsx (opens new window)

import { selection_sort } from '../main'

describe("selection_sort", () => {
  it("main", () => {
    const array = [1, 5, 3, 6, 4, 8, 2, 9, 7];

    expect(selection_sort(array)).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9])
  });
})

实现

  • Langnang.selection_sort

@langnang/js-func/src/selection_sort.ts (opens new window)

/**
 * @name selection_sort
 * @description 选择排序。重复遍历未排序部分,将最小元素移至已排序末尾。
 * @category Array 数组
 * @category Algorithm 算法
 * @category Sorting 排序
 * @tip 算法原理 tip 1. 初始状态:无序区为 R[1..n],有序区为空;\n2. 第 i 趟排序(i=1,2,3…n-1)开始时,当前有序区和无序区分别为 R[1..i-1]和 R(i..n)。该趟排序从当前无序区中-选出关键字最小的记录 R[k],将它与无序区的第 1 个记录 R 交换,使 R[1..i]和 R[i+1..n)分别变为记录个数增加 1 个的新有序区和记录个数减少 1 个的新无序区;\n3. n-1 趟结束,数组有序化了。\n
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} iteratee(element, index, array) 每次迭代调用的函数。
 * * @param {*} a 第一个用于比较的元素。
 * * @param {*} b 第二个用于比较的元素。
 * @returns {Array} 排序后的数组。
 */
export const selection_sort = (array: any[]) => {
  // 选择:将未排序部分中最小值移至已排序部分末尾
  const selection = (array: any[], start: number) => {
    // 取未排序首个元素位置
    let minIndex = start;
    // 遍历未排序部分
    for (let i = start + 1; i < array.length; i++) {
      // 寻找最小的数

      if (array[minIndex] > array[i]) {
        //将最小数的索引保存
        minIndex = i;
      }
    }
    // 交换元素位置
    [array[start], array[minIndex]] = [array[minIndex], array[start]];
  }
  for (let i = 0; i < array.length - 1; i++) {
    selection(array, i);
  }
  return array;
}

# shell_sort

希尔排序。置增量序列/因子,分割数组进行插入排序,直至增量因子为 1。

数组 算法 排序

算法原理

  1. 选择一个增量序列 t1,t2,…,tk,其中 ti>tj,tk=1;
  2. 按增量序列个数 k,对序列进行 k 趟排序;
  3. 每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来 处理,表长度即为整个序列的长度。

添加版本

0.0.1

语法

shell_sort(array, iteratee(element, index, array));

参数

  • array(Array): 需要处理的数组。
  • iteratee(element, index, array)(*): 每次迭代调用的函数。
    • a(*): 第一个用于比较的元素。
    • b(*): 第二个用于比较的元素。

返回值

(Array): 排序后的数组。

示例

@langnang/js-func/test/shell_sort.tsx (opens new window)

import { shell_sort } from '../main'

describe("shell_sort", () => {
  it("main", () => {
    const array = [1, 5, 3, 6, 4, 8, 2, 9, 7];

    expect(shell_sort(array)).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9])
  });
})

实现

  • Langnang.shell_sort

@langnang/js-func/src/shell_sort.ts (opens new window)

/**
 * @name shell_sort
 * @description 希尔排序。置增量序列/因子,分割数组进行插入排序,直至增量因子为 1。
 * @category Array 数组
 * @category Algorithm 算法
 * @category Sorting 排序
 * @tip 算法原理 tip 1. 选择一个增量序列 t1,t2,…,tk,其中 ti>tj,tk=1;\n2. 按增量序列个数 k,对序列进行 k 趟排序;\n3. 每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来 处理,表长度即为整个序列的长度。\n
 * @since 0.0.1
 * @param {Array} array 需要处理的数组。
 * @param {*} iteratee(element, index, array) 每次迭代调用的函数。
 * * @param {*} a 第一个用于比较的元素。
 * * @param {*} b 第二个用于比较的元素。
 * @returns {Array} 排序后的数组。
 */
export const shell_sort = (array: any[]) => {
  const shell = (array: any[], gap: number) => {
    // 插入排序默认第一个元素为已排序,因此跳过gap长度
    for (let i = gap; i < array.length; i++) {
      // 从后向前插入排序
      for (var j = i - gap; j >= 0; j -= gap) {
        // 检测是否需要交换位置
        if (array[j] > array[j + gap]) {
          [array[j], array[j + gap]] = [array[j + gap], array[j]]
        } else {
          // 停止循环
          break;
        }
      }
    }
  }
  for (let gap = array.length / 2; gap > 0; gap = Math.floor(gap / 2)) {
    shell(array, gap);
  }
  return array;
}


# stringify

json转字符串

添加版本

0.0.1

语法

stringify(object);

参数

  • object(*): JSON对象

返回值

(String): 转换后的字符串

实现

  • Langnang.stringify

@langnang/js-func/src/stringify.ts (opens new window)

/**
 * @name stringify
 * @description json转字符串
 * @since 0.0.1
 * @param {*} object `JSON`对象 
 * @returns {String} 转换后的字符串
 */
// TODO
export const stringify = (object: Object): string => JSON.stringify(object);

# sum

计算数组中值的总和

算术

添加版本

0.0.2

语法

sum(nums, iteratee(element, index, array));

参数

  • nums(Array): 需要计算的数组
  • iteratee(element, index, array)(*): 每次迭代调用的函数。
    • element(*): 当前遍历到的元素。
    • index(Number): 当前遍历到的索引。
    • array(Array): 数组本身。

示例

@langnang/js-func/test/sum.tsx (opens new window)

import { sum } from '../main'

describe("sum", () => {
  it("main", () => { });
  it("MDN", () => { });
  it("Lodash.sum", () => {
    expect(sum([4, 2, 8, 6])).toEqual(20);
  });
  it("Lodash.sumBy", () => {
    var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];

    // _.sumBy(objects, function (o) { return o.n; });
    // => 20
    expect(sum(objects, function (o: any) { return o.n; })).toEqual(20);

    // The `_.property` iteratee shorthand.
    // _.sumBy(objects, 'n');
    // => 20
  });
  it("Underscore", () => { });
})

参考

实现

  • Langnang.sum
  • Lodash.sum
  • Lodash.sumBy

@langnang/js-func/src/sum.ts (opens new window)

import { array_reduce } from "./array_reduce";

/**
 * @name sum
 * @description 计算数组中值的总和
 * @category Math 算术
 * @since 0.0.2 
 * @param {Array} nums 需要计算的数组 
 * @param {*} iteratee(element, index, array) 每次迭代调用的函数。
 * * @param {*} element 当前遍历到的元素。
 * * @param {Number} index 当前遍历到的索引。
 * * @param {Array} array 数组本身。
 * @returns{Number} 计算的结果
 * @tutorial https://www.lodashjs.com/docs/lodash.sum
 * @tutorial https://www.lodashjs.com/docs/lodash.sumBy
 */
export const sum = (nums: any[], iteratee: any = null): number => array_reduce(nums, (acc: number, val: any, ind: number, arr: any[]) => acc + (iteratee ? iteratee(val, ind, arr) : val), 0)


# uuid

生成随机通用唯一标识符(Universally Unique Identifier)

添加版本

0.0.1

语法

uuid();

返回值

(String): 通用唯一标识符

示例

@langnang/js-func/test/uuid.tsx (opens new window)

import { uuid } from "../main";

describe("uuid", () => {
  it("uuid", () => {
    expect(uuid().length).toBe(36)
    expect(uuid()).not.toBe(uuid())
  })
})

实现

  • Langnang.uuid

@langnang/js-func/src/uuid.ts (opens new window)

/**
 * @name uuid
 * @description 生成随机通用唯一标识符(Universally Unique Identifier)
 * @since 0.0.1
 * @returns {String} 通用唯一标识符
 */
export const uuid = () =>
  "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) =>
    (c == "x"
      ? (Math.random() * 16) | 0
      : (Math.random() * 16) | (0 & 0x3) | 0x8
    ).toString(16)
  );

# verify_regexp

校验是否匹配正则表达式

添加版本

0.0.2

语法

verify_regexp(string, regexp);

参数

  • string(String): 需要校验的字符串
  • regexp(RegExp): 校验的正则表达式

返回值

(Boolean): 校验结果

实现

  • Langnang.verify_regexp

@langnang/js-func/src/verify_regexp.ts (opens new window)

/**
 * @name verify_regexp
 * @description 校验是否匹配正则表达式
 * @since 0.0.2
 * @param {String} string 需要校验的字符串 
 * @param {RegExp} regexp 校验的正则表达式
 * @returns {Boolean} 校验结果
 */
export const verify_regexp = (string: string, regexp: RegExp): boolean => regexp.test(string)

# verify_sudoku

校验数独结果

添加版本

0.0.1

语法

verify_sudoku(sudoku);

参数

  • sudoku(Array): 需要校验的数独

返回值

(Boolean): 校验结果

实现

  • Langnang.verify_sudoku

@langnang/js-func/src/verify_sudoku.ts (opens new window)

// TODO
/**
 * @name verify_sudoku
 * @description 校验数独结果
 * @since 0.0.1
 * @param {Array} sudoku 需要校验的数独
 * @returns {Boolean} 校验结果
 */
export const verify_sudoku = (sudoku: any[]) => {
  return verify_sudoku_row(sudoku) && verify_sudoku_col(sudoku) && verify_sudoku_block(sudoku)
};
// 校验行
const verify_sudoku_row = (sudoku: any[]) => {
  return sudoku.every(row => [...new Set([...row])].length == 9);
}
// 校验列
const verify_sudoku_col = (sudoku: any[]) => {
  const _result = sudoku.map((v_row: any, index_row: number) => v_row.map((v_col: any, index_col: number) => sudoku[index_col][index_row]));
  return verify_sudoku_row(_result);
}
// 校验块
const verify_sudoku_block = (sudoku: any[]) => {
  let _result: any[] = [];
  let col_center_index_array = [1, 4, 7];
  let row_center_index_array = [1, 4, 7];
  col_center_index_array.forEach(col_center_index => {
    row_center_index_array.forEach(row_center_index => {
      let _block = [];
      for (let y = col_center_index - 1; y <= col_center_index + 1; y++) {
        for (let x = row_center_index - 1; x <= row_center_index + 1; x++) {
          _block.push(sudoku[y][x]);
        }
      }
      _result.push(_block);
    });
  });
  return verify_sudoku_row(_result);
}