#2 javascript算法2

1.用字符串代表数字来进行算术操作

描述:

// 比如
seven( times( five() ) ); // 相当于 7 * 5 = 35
four( plus( nine() ) ); // 4 + 9 = 13
eight( minus( three() ) ); // 8 - 3 = 5
six( dividedBy( two() ) ); // 6 / 3 = 2

看到这个第一眼就有点蒙逼,这肯定要使用高阶函数来完成,但如何实现,内心比较矛盾,最后看了一下别人的算法:

算法1:

["zero", "one", "two", "three", "four", "five", "six", 
     "seven", "eight", "nine"].forEach(function (name, n) {
            this[name] = function(f) {return f ? f(n) : n}
          });

var plus = n =>
   a =>
     a + n;
var minus = n =>
   a =>
     a - n;
var times = n =>
   a =>
     a * n;
var minus = n =>
   a =>
     a / n;

解析:

首先forEach函数利用0-9对应的索引返回一个函数,
如果这个函数参数存在则调用f(n), 如果不存在则直接
等于索引值,即0对应的是0,9对应的是9;

然后就是加减乘除各自也是一个高阶函数。

算法2:与上面类似

const numbers = 'zero one two three four five six seven eight nine'.split(' ')

const number = num => {
  return operator => {
    if (operator) return operator(num)
    return num
  }
}

const operator = op => {
  return x => {
    return y => {
      return op(y, x)
    }
  }
}

// Numbers
numbers.forEach((name, index) => 
  GLOBAL[name] = number(index)
)

// Operators
const plus = operator((x, y) => x + y)
const minus = operator((x, y) => x - y)
const times = operator((x, y) => x * y)
const dividedBy = operator((x, y) => x / y)

2.算出一个字符串中重复的字符个数(忽略大小写)

描述:

"abcde" -> 0 # no characters repeats more than once
"aabbcde" -> 2 # 'a' and 'b'
"aabbcdeB" -> 2 # 'a' and 'b'
"indivisibility" -> 1 # 'i'
"Indivisibilities" -> 2 # 'i' and 's'

我的算法:

function duplicateCount(text) {
 var result = [];
 var finalResult = [];
 // 将text中重复的字符添加到result中
 text.toLowerCase().split("")
  .filter((v, idx, arr) =>
    if (arr.indexOf(v) !== arr.lastIndexOf(v)) {
      result.push(v);
    }
  )
 // 将result中重复的字符去掉
 finalResult = result.filter((v, idx, arr) =>
          arr.indexOf(v) === idx
 );
 return finalResult.length;
}

我的算法虽然可行,但是比较啰嗦。别人的算法,利用正则:

function duplicateCount(text) {
  return (
    text
     .toLowerCase().split("").sort().join("")
     .match(/([^])\1+/g || []).length;
 )
}

// 先讲字符串全变为小写然后变为数组,并且排序
// 然后再将字符按照从小到大组合成字符串
// 正则
// ([^]): 表示任意字符
// (..)\1: 表示前面()的组
// (..)\1+: 表示连着出现2次以及2次以上的

3.将字符串交替的变换大小写

描述:

toWeirdCase( "String" );//=> returns "StRiNg"
toWeirdCase( "Weird string case" );
//=> returns "WeIrD StRiNg CaSe"

做了半天没做出来,当需要多层嵌套时对数组操作时, 最好不要用箭头函数

别人的:

function toWeirdCase(string) {
  return string.split(/\s+/).map(function(word) {
    return word.split("").map(function(letter, i) {
      return (i % 2 === 0) ? letter.toUpperCase() : letter.toLowerCase()
     // 或者
     // return letter[(!(i%2))?"toUpperCase":"toLowerCase"]()
     // 这种表示方法利用对象的特性
    }).join("");
  }).join(" ");
}

本质上是高阶函数的运用, 需要注意的是, 当我们使用map之后,如果需要对内部item,再进行一次map, 这个时候需要返回一个函数, 在返回的函数中对map进行操作

解析:

string.split(/\s+/)
//1. 将字符串出去空格变为数组
// "hello world this" => ["hello", "world", "this"]

string.split(/s+/).map(function(word) {
 // ...
})
// 2.对每个单词进行操作

// 3.这时候需要对每个单词再一次进行map操作
return word.split(""){} 
// 拆成数组 
// ["h", "e", "l", "l", "o"]
// 内部逻辑处理之后合并成一个单词返回
// ["HeLlO", "WoRlD", "ThIs"]

你可能感兴趣的:(#2 javascript算法2)