每日一题

20170830

数组扁平化:

实现一个flatten函数,将一个嵌套多层的数组 array(数组) (嵌套可以是任何层数)转换为只有一层的数组,数组中元素仅基本类型的元素或数组,不存在循环引用的情况。

Ex: flatten([1, [2], [3, [[4]]]]) => [1, 2, 3, 4];

方法一:递归

var arr = [1, [2], [3, [[4]]]];
function flatten(arr) {
    var result = [];
    for (var i = 0; i < arr.length; i++) {
        if (Array.isArray(arr[i])) {
            result = result.concat(flatten(arr[i]));
        } else {
            result.push(arr[I]);
        }
    }
    return result;
}
console.log(flatten(arr));

方法二:reduce

var arr = [1, [2], [3, [[4]]]];
function flatten(arr) {
    return arr.reduce(function (pre, curr) {
        return pre.concat(Array.isArray(curr) ? flatten(curr) : curr)
    }, [])
}
console.log(flatten(arr));

解析:
首先明白concat()和reduce()

  • concat()先创建当前数组的一个副本,然后将接收到的参数添加到这个数组末尾
  • reduce()接收两个参数a和b,a是一个在每一项上调用的函数,b是可选的初始值,以上代码中就是一个空数组[]
  • 函数a接收4个参数,前一个值pre,当前值curr,数组索引index,原数组arr,
  • 函数的返回值作为pre传递给curr,所以pre是数组第一项,curr是数组第二项

说以上代码

  • 将arr传递给flatten函数并在arr调用reduce方法,
  • return pre.concat()可理解为返回了一个唯一项为pre的新数组
  • concat内接收一个三目运算,如果当前值curr不是数组,直接添加到pre中,如果当前值curr是数组,再次执行flatten函数,调用之后还是若curr还是数组,再次执行flatten函数,循环调用flat函数直到curr不是一个数组为止

有深度拉平数组⬇️

function flattenDownDepth(array, result, depth) {
    depth--
    for (var i = 0; i < array.length; i++) {
        var value = array[I];
        if (depth > -1 && Array.isArray(value)) {
            flattenDownDepth(value, result, depth)
        } else {
            result.push(value)
        }
    } return result
}

var arr = [1, [1, [1, [23, 32], 32], 3232], [[3]], [4]];
var result = [];
var depth = 0;

flattenDownDepth(arr, result, depth);
console.log(result);

20170831

CSS实现模态框

纯CSS实现,点击按钮显示一个modal,再点击关闭按钮,关闭modal。

每日一题_第1张图片
需要实现的效果




    
    
    
    Modal
    



    

20170901

reduce

实现一个reduce函数,作用和原生的reduce类似。
reduce(list, iteratee, [memo]),memo是reduce函数的初始值,会被每一次成功调用iteratee函数的返回值所取代 。这个迭代传递4个参数:memo,value 和 迭代的index和最后一个引用的整个 list。如果没有memo传递给reduce的初始调用,iteratee不会被列表中的第一个元素调用。第一个元素将取代memo参数传递给列表中下一个元素调用的iteratee函数。
Ex:var sum = reduce([1, 2, 3], function(memo, num){ return memo + num; }, 0);
=> 6

function reduce(arr, iteratee, initValue){
  var tmpArr = (initValue === undefined ? [] : [initValue]).concat(arr)
  while(tmpArr.length > 1){
    tmpArr.splice(0, 2, iteratee(tmpArr[0], tmpArr[1]))
  }
  return tmpArr[0]
}

var sum = reduce([3,5], function(v1, v2){
  return v1 * v2
},4)
console.log(sum)

20170902

CSS实现如下效果

每日一题_第2张图片
效果图
//html部分



  
  JS Bin


    
//css部分

/*方法一:float: right*/
ul,
li {
    list-style: none;
}

ul {
    float: left;
}

li {
    border: 2px solid black;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    float: right;
    margin: 0 20px;
}

li:hover,
li:hover~li {
    background: #cdcdcd;
}


/*方法二:flex-direction:row-reverse*/
ul {
    display: flex;
    flex-direction: row-reverse;
    position: absolute;
    left: 0;
}

ul,
li {
    list-style: none;
}

li {
    border: 2px solid black;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    margin: 0 20px;
    background: white;
}

li:hover,
li:hover~li {
    background: #cdcdcd;
}


/*方法三:flex布局中的order,本题可实现,但不太实用,代码量也多*/
ul {
    display: flex;
}

li {
    list-style: none;
    border: 2px solid black;
    height: 50px;
    width: 50px;
    border-radius: 50%;
    margin-right: 20px;
}

li:hover,
li:hover~li {
    background: #cdcdcd;
}

li:first-child {
    order: 5;
}

li:nth-child(2) {
    order: 4;
}

li:nth-child(3) {
    order: 3;
}

li:nth-child(4) {
    order: 2;
}

li:last-child {
    order: 1;
}

/* 方法四:inline-block,没人规定背景色必须是白色,选中后才是灰色啊,我可以背景色是灰色,选中后,选中的仍是灰色,未选中的是白色 */
ul,
li {
    list-style: none;
}

li {
    display: inline-block;
    border: 2px solid black;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    margin: 0 20px;
    background: #cdcdcd;
}

li:hover~li {
    background: white;
}

20170903

实现一个map函数,模拟原生map函数

function map(arr,fn){
  var result=[]
  for(var i=0;i

20170904

实现一个find函数,模拟原生的find函数,find(list, predicate)。

在list中逐项查找,返回第一个通过predicate迭代函数真值检测的元素值,如果没有元素通过检测则返回 undefined。 如果找到匹配的元素,函数将立即返回,不会遍历整个list。

function find(list, fn) {
    for (var i = 0; i < list.length; i++) {
        if (fn(list[i])) return list[i]//只要fn有返回值,就返回list[I]
    }
}
var event = find([1, 2, 3, 4, 5], function (num) {
    return num % 2 == 0
})
console.log(event)//2

20170905

实现一个filter函数,模拟原生的filter函数,filter(list, predicate)。
遍历list中的每个值,返回所有通过predicate真值检测的元素所组成的数组。

function filter(arr, fn) {
    var res = []
    for (var i = 0; i < arr.length; i++) {
        if (fn(arr[i])) {
            res.push(arr[i])
        }
    }
    return res
}

var events = filter([1, 2, 3, 4, 5, 6], function (num) {
    return num % 2 == 0
})
console.log(events)//[2,4,6]

20170908

实现一个parseQuery函数,能够解析location的search字符串(不包括’?’)。输入一个search,输出一个object,同名参数则是会成为数组

function parseQuery(str) {
    var res = {}
    var reg = /([^&=\s]+)[=\s]?([^&=\s]*)/g
    str.replace(new RegExp(reg), function (match, key, value) {//replace方法第一个参数是一个RegExp对象时,match表示匹配的子串,match后的参数表示第几个捕获组
        if (!res[key]) {//如果值不存在,在对象内添加这个键值对
            res[key] = value
        } else {//如果值存在,将这个值保存在origin变量中,检测origin为数组时,直接push值
            var origin = res[key]
            if (Array.isArray(origin)) {
                res[key].push(value)
            } else {//如果不是数组了,用数组包裹多个值)
                res[key] = [origin, value]
            }
        }
    })
    return res
}
var search = 'name=dot&age=2&fav=milk&fav=orange&like&fav=apple'
console.log(parseQuery(search))

20170911

实现一个create函数,模拟原生的new操作符。

每日一题_第3张图片
function Person(name, age) {
    this.name = name
    this.age = age
}

Person.prototype = {
    prototype: 'type'
}

function create(constructor) {
    var args = Array.prototype.slice.call(arguments, 1)//将传进来的参数转化为数组并借用数组的slice方法获取索引为1(包括索引1的项)的项开始的所有项,索引为0的项是传进来的constructor
    var obj = {}//创建一个空对象
    obj.__proto__ = constructor.prototype//将新创建的对象的原型指向构造函数的原型
    var res = constructor.apply(obj, args)//apply接受两个参数,第一个是this,第二个是参数数组,res是调用Person后得到的结果对象
    if (typeof res === 'object' && res !== null) {
        return res
    }
    return obj
}

var test = create(Person, 'dot', 2)
console.log(test)//{name:'dot,age:2}
console.log(test.prototype)//type

20170913

实现一个函数,将浮点数左边的数每三位添加一个逗号

function commafy(num) {
    return num.toString().replace(/(\d)(?=(\d{3})+\.?)/g, function ($2) {
        return $2 + ','
    })
}
console.log(commafy(1200000000.11))
console.log(commafy(123246723749.213769283))

20170918

有两个从小到大已经排序完成的数组,长度分别是n和m,单个数组的不存在重复元素,问如何在m+n次操作下,完成去重,得到一个完整的非重数组。

function distinctBySortArray(arr1, arr2) {
    //copyarr1生成一个新数组result
    var result = arr1.concat()
    //遍历arr2中的每一项
    for (var i = 0; i < arr2.length; i++) {
        //新数组result中没有与arr2[i]重复的项则将arr2[i]添加到result末尾
        if (result.indexOf(arr2[i]) === -1) {
            result.push(arr2[I])
        }
    }
    return result.sort(compare)
}

function compare(val1, val2) {
    return val1 - val2
}

var arr1 = [1, 3, 5, 6]
var arr2 = [4, 5, 6, 7, 8, 9]

console.log(distinctBySortArray(arr1, arr2))
console.log(arr1)
console.log(arr2)

20170920

使用 localStorage封装一个 Storage 对象,达到如下效果:


每日一题_第4张图片
var Storage = (function () {
    return {
        set: function (key, values, expiredSeconds) {
            //设置的是一个JSON格式的字符串
            localStorage[key] = JSON.stringify({
                value: values,
                expired: expiredSeconds === undefined ? undefined : Date.now() + 1000 * expiredSeconds//如果不存在第三个参数(即数据永久有效),返回undefined,如果存在,返回当前时间加上设定的时间(即生效截止日期)

            })
        },
        get: function (key) {
            if (localStorage[key] === undefined) {
                return//如果localStorage中只有键名没有对应键值,则直接return undefined,如Storage.set('name'); console.log(Storage.get('name'))  ==>undefined
            }
            //获取的是一个js对象
            var obj = JSON.parse(localStorage[key])//localStorage得到的键值是一个JSON格式的字符串,obj为JSON字符串反序列化得到的js对象
            if (obj.expired === undefined || Date.now() < obj.expired) {//如果expired没有被设置过,即永久有效时,或者当前时间小于设置时间,即还在有效期内时,返回js对象的值
                return obj.value
            } else {//否则删除键值
                delete localStorage[key]//删除键值后再获取键值得到的是undefined
            }
        }
    }
})()

Storage.set('name', '饥人谷')
Storage.set('age', 2, 30);  //设置 name 字段存储的值为'饥人谷'
Storage.set('teachers', ['ruoyu', 'fangfang', 'tom'], 60)

Storage.get('name')
Storage.get('age')
Storage.get('teachers')

20170928

创建一个compose函数,返回函数集 functions 组合后的复合函数, 也就是一个函数执行完之后把返回的结果再作为参数赋给下一个函数来执行. 以此类推. 在数学里, 把函数 f(), g(), 和 h() 组合起来可以得到复合函数 f(g(h()))。

function compose() {
    var fns = [].slice.call(arguments)
    return function (initialArg) {
        var res = initialArg
        for (var i = fns.length - 1; i > -1; i--) {
            res = fns[i](res)
        }
        return res
    }
}

function pipe() {
    var fns = [].slice.call(arguments)
    return function (initialAgr) {
        var res = initialAgr
        for (var i = 0; i < fns.length; i++) {
            res = fns[i](res)
        }
        return res
    }
}

var greet = function (name) { return 'hi:' + name }
var exclaim = function (statement) { return statement.toUpperCase() + '!' }
var transform = function (str) { return str.replace(/[dD]/, 'DDDDD') }
var welcome1 = compose(greet, exclaim, transform)
var welcome2 = pipe(greet, exclaim, transform)
console.log(welcome1('dot'))//hi:DDDDDOT!
console.log(welcome2('dolb'))//HI:DDDDDOLB!

20170929

创建一个before函数,调用不超过count 次。 当count已经达到时,最后一个函数调用的结果将被记住并返回。

每日一题_第5张图片
image
function before(count, fn) {
    var n = 0
    return function () {
        n++
        if (n >= count) {
            return fn(count - 1)
        }
    }
}

var fn = function () {
    console.log([].slice.call(arguments))
}
var monthlyMeeting = before(3, fn)
monthlyMeeting()
monthlyMeeting()
monthlyMeeting()
monthlyMeeting()

20171009

实现一个range函数,range([start], stop, [step]),一个用来创建整数灵活编号的列表的函数,便于each 和 map循环。如果省略start则默认为 0;step 默认为 1.返回一个从start 到stop的整数的列表,用step来增加 (或减少)独占。值得注意的是,如果stop值在start前面(也就是stop值小于start值),那么值域会被认为是零长度,而不是负增长。如果你要一个负数的值域 ,请使用负数step.

![](http://upload-images.jianshu.io/upload_images/6851923-0e959d8b15c062ee.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

function range(start, stop, step) {
    if (stop == null) {
        stop = start || 0
        start = 0
    }
    step = step || 1

    var length = Math.max(Math.ceil((stop - start) / step), 0)
    var result = Array(length)

    for (var i = 0; i < length; i++ , start += step) {
        result[i] = start
    }
    return result
}

console.log(range(10))//[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
console.log(range(1, 11))//[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
console.log(range(1, 11, 1.2))
//[ 1,
//   2.2,
//   3.4000000000000004,
//   4.6000000000000005,
//   5.800000000000001,
//   7.000000000000001,
//   8.200000000000001,
//   9.4,
//   10.6 ]
console.log(range(2, 2))//[]
console.log(range(0, 30, 5))//[ 0, 5, 10, 15, 20, 25 ]
console.log(range(0))//[]

20171010

实现有一个groupBy函数,把一个集合分组为多个集合,通过 iterator 返回的结果进行分组。

每日一题_第6张图片
function groupBy(arr, fn) {
    var res = {}
    arr.forEach(function (val) {
        var key = fn(val)
        if (res[key]) {
            res[key].push(val)//此键有值则将当前值push进已有的值数组中
        } else {
            res[key] = [val]//此键无值则赋值
        }
    }, this);
    console.log(res)
}

groupBy([1.3, 1.4, 1.2, 3.8, 2.9], function (num) {
    return Math.floor(num)
})
//{1:[1.3,1.4,1.2],2:[2.9],3:[3.8]} 

20171016

创建一个函数,输入一个链表,输出一个数组,数组中的值是链表中的值的逆序输出。
计算机中以1对1方式存数据结构分两种:1.数组 2.链表,如果数据写入和删除操作十分频繁,链表结构优于数组。链表的解释如下:

链表由多个不连续的,独立的节点(LinkNode)链接起来,构成的线性结构。每个节点中最少存在两个属性,一个属性(val)用于保存该节点需要的数据,另一个属性(next),确切说是引用(指针),用于找到下一个节点。

function printListFromTailToHead(head) {
    var arr = []
    while (head) {
        //数组的unshift方法用于在数组前端添加项,即值是按照1,2,3的顺序依次添加到最前面,最后看起来就是倒序排列了
        arr.unshift(head.element)
        head = head.next
    }
    return arr
}

var head = {
    element: 1,
    next: {
        element: 2,
        next: {
            element: 3,
            next: null
        }
    }
}

console.log(printListFromTailToHead(head))//[ 3, 2, 1 ]

20171017

创建一个函数,实现链表的push(链表尾追加一个node)和pop(链表尾删除一个node),具有pop和push方法的链表,一般称之为堆栈,特点是先进后出。

function push(head, node) {
    // 链表为空直接将 head 指向新元素,返回head
    if (head === null) {
        head = node
        return head
    } else {
        // 链表不为空则将当前head保存在current变量中,再通过head,next遍历链表的每一项,如果下一个元素存在,则将head指向下一个元素,一直到指向最后一个元素
        var current = head
        while (head.next) {
            head = head.next
        }
        // 然后将最后一个元素的 next 属性指向新元素
        head.next = node
        //返回保存有所有元素的current变量
        return current
    }
}

function pop(head) {
    // 链表不为空则将当前head保存在current变量中,再通过head,next遍历链表的每一项,如果下一个元素存在,则将head指向下一个元素,一直到指向最后一个元素
    var current = head
    var temp
    while (head.next) {
        temp = head
        head = head.next
    }
    if (!temp) throw new Error('head have to more than one node')
    //将最后一项设为空
    temp.next = null
    return current
}


var head = {
    element: 1,
    next: {
        element: 2,
        next: {
            element: 3,
            next: null
        }
    }
}

var node = { element: 4, next: null }

console.log(push(head, node))
// { element: 1,
//   next: { element: 2, 
//     next: { element: 3, 
//       next: { element: 4, 
//         next: null } } } }

console.log(push(null, { element: 5, next: null }))
//{ element: 5, next: null }

console.log(pop(head))
//{ element: 1,
//    next: { element: 2, 
//      next: { element: 3, 
//        next: null } } }

console.log(pop(head))
//{ element: 1,
//    next: { element: 2, 
//      next: null } }

20171018

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

//以下是我的写法,有点搞不懂题目的意思???方方老师说他也不懂题目的意思,不就是找最小值吗?跟旋转有毛关系?

//求数组最小值
function minNumberInRotateArray(array) {
    if (array.length === 0) return 0
    var min = array[0]
    array.forEach(function (item) {
        if (item < min) {
            min = item
        }
    })
    return min
}

//求数组最小值
Array.prototype.min=function(){
    return Math.min.apply({},this)
}

//求数组最大值
function maxNumberInRotateArray(array) {
    if (array.length === 0) return 0
    var max = array[0]
    array.forEach(function (item) {
        if (item > max) {
            max = item
        }
    })
    return max
}

//求数组最大值
Array.prototype.max=function(){
    return Math.max.apply({},this)
}

var array = [6501, 6828, 6963, 7036, 7422, 7674, 8146, 8468, 8704, 8717, 9170, 9359, 9719, 9895,
    9896, 9913, 9962, 154, 293, 334, 492, 1323, 1479, 1539, 1727, 1870, 1943, 2383, 2392,
    2996, 3282, 3812, 3903, 4465, 4605, 4665, 4772, 4828, 5142, 5437, 5448, 5668, 5706,
    5725, 6300, 6335];

var arr = []

console.log(minNumberInRotateArray(array))//154
console.log(minNumberInRotateArray(arr))//0
console.log(maxNumberInRotateArray(array))//9962
console.log(maxNumberInRotateArray(arr))//0
console.log(array.max())//9962
console.log(array.min())//154

20171019

斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。(n<=39,且n以1开始,不是以0开始的,如1代表斐波那契数列第一项。)

每日一题_第7张图片
function fibonacci(n) {
    if (n >= 1 && n <= 39) {
        return n < 3 ? n - 1 : (fibonacci(n - 1) + fibonacci(n - 2))
    }
}
console.log(fibonacci(1))
console.log(fibonacci(2))
console.log(fibonacci(3))
console.log(fibonacci(4))
console.log(fibonacci(40))

20171025

输入一个链表,输出该链表中倒数第k个结点。

function findKthToTail(head, k) {
    if (head === null || k <= 0) { return null }
    var pre = head
    var last = head
    for (var i = 0; i < k; i++) {
        if (pre.next != null) {
            pre = pre.next
        } else {
            return null
        }
    }
    while (pre.next != null) {
        pre = pre.next
        last = last.next
    }
    return last
}

var head = {
    element: 1,
    next: {
        element: 2,
        next: {
            element: 3,
            next: {
                element: 4,
                next: null
            }
        }
    }
}
console.log(findKthToTail(head, 1))
//{ element: 3, next: { element: 4, next: null } }

console.log(findKthToTail(head, 2))
//{ element: 2,
  next: { element: 3, next: { element: 4, next: null } } }

console.log(findKthToTail(head, 3))
//{ element: 1,
  next: { element: 2, next: { element: 3, next: { element: 4, next: null } } } }

console.log(findKthToTail(head, 4))
//null

20171026

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变

//方法一:定义新数组

function reOrderArray(arr) {
    //定义一个奇数数组,一个偶数数组
    var oddArr = []
    var evenArr = []
    //遍历数组
    arr.forEach(function (item) {
        var num = item / 2
        //如果num是整数,则item是偶数,将item push到偶数数组
        if (parseInt(num) === num) {//换成if (item % 2 === 1)也可以,就不需要定义num变量了
            evenArr.push(item)
            //否则push到奇数数组
        } else {
            oddArr.push(item)
        }
    }, this)
    //返回奇数在前偶数在后,奇数偶数分别来看,相对位置不变的数组
    return oddArr.concat(evenArr)
}

//同种方法reduce写法
// function reOrderArray3(arr) {
//     return arr.reduce((prev, curr) =>
//         (curr & 1 ? prev[0].push(curr) : prev[1].push(curr), prev), [[], []])
//         .reduce((prev, curr) => prev.concat(curr))
// }

console.log(reOrderArray([2, 8, 5, 3, 9, 7, 6, 4, 0]))//[ 5, 3, 9, 7, 2, 8, 6, 4, 0 ]
console.log(reOrderArray([0, 1, 2, 9, 8, 7, 13, 92, 66, 50, 23]))//[ 1, 9, 7, 13, 23, 0, 2, 8, 92, 66, 50 ]
//方法二:直接在原数组上操作

function reOrderArray(arr) {
    //定义一个代表偶数个数的变量初始化为0
    var evenNumCount = 0
    //遍历数组的每一项,每找到一个偶数,需要遍历的数组长度就减1
    for (var i = 0; i < arr.length - evenNumCount; i++) {
        //&运算数字,两边都转换成二进制,
        //例如,1&1===1,2&1===0,3&1===1,
        //至此得到结论,奇数&1===1,偶数&1===0,
        //本题中,奇数在前偶数灾后,所以我们让奇数保持不变,只变换偶数的位置,
        //arr[i]为偶数时,if内判断条件才为true)
        if (!(arr[i] & 1)) {
            //如果是偶数,删除它,并将它添加到数组末尾,
            //其中arr.splice(i, 1)返回的是删掉的元素组成的数组,这里我们只删掉了一项,所以arr.splice(i, 1)[0]实际上就是我们删掉的arr[i]
            arr.push(arr.splice(i, 1)[0])
            //每删除一项及push该项,要遍历的项就少了一项,偶数个数增加一个,执行i--是为了填补遍历空缺,不漏项
            I--
            evenNumCount++
        }
    }
    return arr
}

console.log(reOrderArray([2, 8, 5, 3, 9, 7, 6, 4, 0]))//[ 5, 3, 9, 7, 2, 8, 6, 4, 0 ]
console.log(reOrderArray([0, 1, 2, 9, 8, 7, 13, 92, 66, 50, 23]))//[ 1, 9, 7, 13, 23, 0, 2, 8, 92, 66, 50 ]

20171027

在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组[2,3,1,0,2,5,3],那么对应的输出是第一个重复的数字2。

function find_dup(nums) {
    var n = nums.length
    for (var i = 0; i < n; i++) {
        var idx = nums[I]
        if (idx >= n) {
            idx -= n
        }
        if (nums[idx] >= n) {
            return idx
        }
        nums[idx] = nums[idx] + n
    }
    return -1
}
console.log(find_dup([1, 2, 3, 4, 5, 4, 3, 2, 1]))//4

20171127

每日一题_第8张图片
function accum(str) {
    var arr = str.split('')
    return arr.map(function (val, index) {
        for (var i = 0; i < index; i++) {
            val += val[i].toLowerCase()
        }
        return val.replace(/( |^)[a-z]/g, (a) => a.toUpperCase())
    }).join('-')
}

console.log(accum('abcd'))
console.log(accum('HeLlowOrld'))
console.log(accum('DOooootdolBY'))

20171207

输入一个数组arr,找出其中和为NUM的对,以数组形式输出,例如:输入:[1,2,3,4,5,5,4,3,2,1,4,4,8,9],NUM = 10
输出:[ [ 1, 9 ],[ 2, 8 ], [ 5, 5 ] ]

本题有很多坑,比如,有很多重复的数字,再比如,存在中间数的情况,要先考虑中间数再来去重

function getSumGroup(arr, sum) {
    var res = []
    //如果中间数有两个或以上,直接push一对值进res
    if (arr.lastIndexOf(sum / 2) !== arr.indexOf(sum / 2)) {
        res.push([sum / 2, sum / 2])
    }
    //数组去重
    //ES6写法
    // arr = Array.from(new Set(arr))
    //面试题可能不准用ES6写法,去重如下
    for (let i = 0; i < arr.length; i++) {
        for (let j = i + 1; j < arr.length; j++) {
            if (arr[i] === arr[j]) {
                arr.splice(i--, 1)
            }
        }
    }
    //循环遍历
    for (var i = 0; i < arr.length; i++) {
        for (var j = 1; j < arr.length; j++) {
            if (arr[i] + arr[j] === sum) {
                res.push([arr[i], arr[j]])
                arr.splice(i, 1)
                arr.splice(j - 1, 1)
                i--
            }
        }
    }
    return res;
}

var arr = [1, 2, 3, 5, 5, 9, 0, 0, 2, 8, 9, 10, 9, 9, 7, 7, 9, 6, 9, 1, 1, 4, 4, 5, 5, 7, 3, 2, 1, 4, 4, 8, 9],
    NUM = 10
console.log(getSumGroup(arr, NUM))

20171214

function foo(x,y,z,...args) {
    console.log( x, y, z, args );
}

foo()//undefined,undefined,undefined,[]
foo( 1, 2, 3 );//1,2,3,[]       
foo( 1, 2, 3, 4 );//1,2,3,[4]   
foo( 1, 2, 3, 4, 5 )//1,2,3,[4,5]
function foo(x = 3) {
    console.log( x );
}
foo( undefined )//3
foo( null )//null

推荐阅读:
使用JavaScript获取URL参数

你可能感兴趣的:(每日一题)