JS算法

/**
 * @description 数组去重
 * @param {number[]} arr
 */

exports.uniqueByObj = (arr) => {
    if(!Array.isArray(arr)) {
        console.log('type error')
        return
    }
    // 利用object的属性key不能相同特点来进行筛选
    let hash = {}
    let results = []
    for(let i = 0; i< arr.length; i++) {
        if(!hash[arr[i]]) { //!hash[arr[i] 为 true
            hash[arr[i]] = true
            results.push(arr[i])
        }
    }
    return results
}

exports.uniqueByIndexOf = (arr) => {
    if(!Array.isArray(arr)) {
        console.log('type error')
        return
    }
    // 数组下标判断法,当值不在新数组时,就加入该数组,如果在就不加了
    let results = []
    for(let i = 0; i < arr.length; i++) {
        if(results.indexOf(arr[i]) === -1) {
            results.push(arr[i])
        }
    }
    return results
}

exports.uniqueByTwoLoop = (arr) => {
    if(!Array.isArray(arr)) {
        console.log('type error')
        return
    }
    // 优化遍历数组法(推荐) 双层循环,(检测到有重复值时终止当前循环同时进入外层循环的下一轮判断)
    let results=[];
    for (let i = 0; i < arr.length; i++) {
      for (let j = i+1; j < arr.length; j++) {
        if(arr[i] === arr[j]){
          ++i;
        }
      }
      results.push(arr[i]);
    }
    return results;
}

exports.uniqueBySet = (arr) => {
    if(!Array.isArray(arr)) {
        console.log('type error')
        return
    }
    // ES6中的Set数据结构,类似于数组,它的成员都是唯一的 ,其构造函数可以接受一个数组作为参数
    // ES6中Array新增了一个静态方法Array.from,可以把类似数组的对象转换为数组
    let set = new Set(arr)
    return Array.from(set)
}

exports.uniqueBySetSimple = (arr) => {
    if(!Array.isArray(arr)) {
        console.log('type error')
        return
    }
    return [...new Set(arr)]
}

exports.uniqueByIncludes = (arr) => {
    if(!Array.isArray(arr)) {
        console.log('type error')
        return
    }
    let results = []
    for(let i=0;i { // 冒泡排序
    for(let i = 0; i < arr.length - 1; i++) {
        for(let j = i+1; j < arr.length; j++) {
            if(arr[i] > arr[j]) { //相邻元素两两对比
                let tem = arr[i] //元素交换
                arr[i] = arr[j]
                arr[j] = tem
            }
        }
    }
    return arr
 }
exports.bubbleSort1 = arr => { // 这种方式比上一种更快 当i=0的时候,里面的循环完整执行,从j=0执行到j=6,这也就是第一遍排序,结果是将最大的数排到了最后
  // 当i=1的时候,里面的循环再次完整执行,由于最大的数已经在最后了,没有必要去比较数组的最后两项,这也是j arr[j+1]) {
        let temp = arr[j]
        arr[j] = arr[j+1]
        arr[j+1] = temp
      }
    }
  }
  return arr
}
 /**
 * @description 快速排序, 对冒泡排序的改进
 * @param {number[]} arr
 */
exports.quickSort = (arr) => {
    if(arr.length <= 1) {
        return arr
    }
    let pivotIndex = Math.floor(arr.length / 2)
    let pivot = arr.splice(pivotIndex, 1)[0]
    let left = []
    let right = []
    for(let i=0;i {
  let minIndex, temp
  for(let i = 0;i < arr.length - 1; i++) {
    minIndex = i
    for(let j = i + 1; j < arr.length; j++) {
      if(arr[j] < arr[minIndex]) {
        minIndex = j
      }
    }
    temp = arr[i]
    arr[i] = arr[minIndex]
    arr[minIndex] = temp
  }
  return arr
}
/**
 * @description 水仙花数,水仙花数是一种特殊的三位数,它的特点就是,每个数位的立方和,等于它本身
 * @param {number} num
 */

 exports.daffodil = (num) => {
     let results = []
     for(let i=100;i {
    let low = 0, high = nums.length -1;
    let sum = 0
    while(low < high) {
        sum = nums[low] + nums[high] // 数组两端的数字相加,与目标数字比较
        if(sum > target) { // 如果和大于目标数字,就将数组索引大的减少1
            high --
        } else if (sum < target) { // 如果和小于目标数字,就将数组索引大的加1
            low++
        } else { // 知道等于目标数字,输出此时数组的索引,记得都加1,或者知道索引大的等于索引小的,输出[-1, -1]
            return [low, high]
        }
    }
    return [-1, -1]
};

/**
 * @description 二分查找,非递归算法
 * @param {number[]} arr
 * @param {number} key
 */
// 在有序数组中查找特定元素的搜索算法, 返回目标元素索引值
exports.binarySearch = (arr, key) => {
    if(!contains(key)) {
        return
    }
    let low = 0, high = arr.length - 1
    while(low <= high) {
        let mid = parseInt((high + low) / 2)
        if(key == arr[mid]) {
            return mid
        } else if(key > arr[mid]) {
            low = mid + 1
        } else if(key < arr[mid]) {
            high = mid - 1
        } else {
            return -1
        }
    }
}

/**
 * @description 判断元素是否存在数组中
 * @param {number[]} arr
 * @param {number} obj
 */
const contains = function(arr, obj) {
    let i = arr.length;
    while (i--) {
      if (arr[i] === obj) {
        return true;
      }
    }
    return false;
}

/**
 * @description 阶乘 n! = n*(n-1)...21 , 6! = 6 * 5 * 4 * 3 * 2 *1
 * @param {number} number
 */
const factorial = function(number) {
    if(number == 1) {
        return number
    } else {
        // return number*factorial(number - 1)  or
        return number*arguments.callee(number - 1) // arguments.callee 表示拥有arguments对象的函数
    }
}
/**
 * @description 斐波那契数列
 * @param {number} number
 */
// 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ... 求第n个数是多少
// 规律:后一项是前两项的和
const fibonacci = function(number) {
    if(number <= 2) {
        return 1
    }
    return fibonacci(number - 1) + fibonacci(number - 2)
}


/*
* 删除数组对象中多个数组元素
* { list } 数组对象 [{},{}]
* { currentSelected } 数组对象 [{},{}]
*/
const updataSearchList = (list, currentSelected) => {
    for(var i = 0;i b.map(itemB => {
    return itemB.guid
}).indexOf(item.guid) < 0)

// 如果有不断变化的数字,只取前一个和当前值
let arr = [0, 0] 默认是0
function foo (data) {
  arr. shift() 删掉第一个元素
arr[1] = data
}
/**
 * @description 将数组平铺到指定的深度
 */
const flatten = (arr, depth = 1) => 
    depth != 1 ? arr.reduce((a, v) => a.concat( Array.isArray(v) ? flatten(v, depth - 1) : v), [])
    : arr.reduce((a, v) => a.concat(Array.isArray(v) ? flatten(v) : v), [])
/**
 * @description 将数组扁平化并去重排序
 */
function flatten(arr) {
    const res = arr.reduce((a, v) => a.concat(Array.isArray(v) ? flatten(v) : v), [])
    return Array.from(new Set(res)).sort((a, b) => a - b)
}
或者用 内置的flat(Infinity)平铺数组

/**
 * @description 取整 | 0
 */
const getInt = num => num | 0

// 截取数组,按照给定的数字
function sliceArray (num) {
  let result = []
  for (let i=0;i < arr.length; i++){
    if(i % num === 0) {
        result.push(arr.slice(i, i + num))
    }
  }
}

// 取前一个和当前的元素
let arr = [] // 放在外面
function foo(value) {
  arr.shift()
  arr[1] = value
}

// 创建随机数
  rndId (n) {
      let rnd = ''
      for(let i = 0; i < n; i++)
        rnd += Math.floor(Math.random() * 10)
      return rnd
    },
// 点击弹窗外元素消失
    const this_ = this
    const stopClick = function (event) {
      event.stopPropagation()
    }
    const popoverHandler = function (e) {
      const el = e.target || e.srcElement
      if (!this_.clickInner) {
        this_.isSearching = false
        this_.searchResult = []
      }
      this_.clickInner = false // 在弹窗事件上设置true
    }
    document.addEventListener('click', popoverHandler)

    /**
     * @description 数字转为字母
     * @param {Number} n 数字
     */
    createCellPos( n ){
      const ordA = 'A'.charCodeAt(0)
      const ordZ = 'Z'.charCodeAt(0)
      const len = ordZ - ordA + 1
      let s = ''
      while( n >= 0 ) {
        s = String.fromCharCode(n % len + ordA) + s
        n = Math.floor(n / len) - 1
      }
      return s
    },

你可能感兴趣的:(JS算法)