1.计算一个范围数字之和
我们会传递给你一个包含两个数字的数组。返回这两个数字和它们之间所有数字的和。
sumAll([1, 4])应该返回 10。
sumAll([10, 5])应该返回 45。
这里可以用到 array.reduce()
太长了我就不粘了,点这里看详细介绍
总之就是会对数组中每个元素执行一次回调函数,累加可以用下面的代码
var total = [0, 1, 2, 3].reduce(function(a, b) {
return a + b;
});
// total == 6
然后再找到哪个数大,哪个数小
var maxnum = Math.max(arr[0],arr[1]);
var minnum = Math.min(arr[0],arr[1]);
然后在他们之间循环push进新数组
for(var i = minnum + 1 ; i < maxnum; i++) {
arr.push(i);
}
对新数组执行reduce就可以了
总体代码
function sumAll(arr) {
var maxnum = Math.max(arr[0],arr[1]);
var minnum = Math.min(arr[0],arr[1]);
for(var i = minnum + 1 ; i < maxnum; i++) {
arr.push(i);
}
return arr.reduce(function(a,b) {
return a+b;
});
}
sumAll([1, 4]);
2.找两个数组的差异
比较两个数组,然后返回一个新数组,该数组的元素为两个给定数组中所有独有的数组元素。换言之,返回两个数组的差异。
[1, 2, 3, 5], [1, 2, 3, 4, 5]应该返回 [4]。
[1, "calf", 3, "piglet"], [1, "calf", 3, 4]应该返回 ["piglet", 4]。
这个很简单,先找数组一中不被数组二包含的元素,再找出数组二中不被一包含的元素,push进新数组。
判断一个数组是不是包含某个元素,可以用arr.indexOf()
,该方法会返回元素在数组中的位置,如果数组中没有这个元素,则返回 -1 ,所以可以用这个方法判断一个数组是不是包含某个元素
function diff(arr1, arr2) {
var newArr = [];
for(var i = 0; i < arr1.length; i++) {
if (arr2.indexOf(arr1[i]) < 0) {
newArr.push(arr1[i]);
}
}
for(var j = 0; j < arr2.length; j++) {
if(arr1.indexOf(arr2[j]) < 0) {
newArr.push(arr2[j]);
}
}
return newArr;
}
diff([1, "calf", 3, "piglet"], [7, "filly"]);
3.将给定的数字转换成罗马数字
convert(2)应该返回 "II"。
convert(29)应该返回 "XXIX"。
convert(798)应该返回 "DCCXCVIII"。
convert(3999)应该返回 "MMMCMXCIX"。
这一题我想了好久不会做,最后看的别人的解法,非常简洁,代码如下。
function convert(num) {
var alb = [1000,900,500,400,100,90,50,40,10,9,5,4,1];
var roma = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"];
var roman = "";
for(var i=0;i<alb.length;i++) {
while(num>=alb[i]) {
roman = roman + roma[i];
num = num - alb[i];
}
}
return roman;
}
convert(36);
4.Where art thou
写一个 function,它遍历一个对象数组(第一个参数)并返回一个包含相匹配的属性-值对(第二个参数)的所有对象的数组。如果返回的数组中包含 source 对象的属性-值对,那么此对象的每一个属性-值对都必须存在于 collection 的对象中。
例如,如果第一个参数是 [{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }]
,第二个参数是 { last: "Capulet" }
,那么你必须从数组(第一个参数)返回其中的第三个对象,因为它包含了作为第二个参数传递的属性-值对。
function where(collection, source) {
var arr = [];
var sss = Object.keys(source);
var rel = [];
// What's in a name?
for(var i=0; i<collection.length; i++) {
for(var j=0; j<sss.length; j++) {
if(collection[i][sss[j]] == source[sss[j]]) {
rel.push(0);
} else {
rel.push(1);
}
}
if (rel.indexOf(1)<0) {
arr.push(collection[i]);
} else{
rel = [];
}
}
return arr;
}
where([{ "a": 1, "b": 2 }, { "a": 1 }, { "a": 1, "b": 2, "c": 2 }], { "a": 1, "b": 2 });
这个我用的方法有点复杂,先用Object.keys()获取source
里面所有可枚举属性的属性名并赋值给sss
,这里如果source
为{ "a": 1, "b": 2 }
,那么Object.keys(source)
会返回["a',"b"]
,然后进行两次遍历判断,为了确定数组每个元素的所有属性都与source
相等先遍历collection
,然后对每个collection
遍历sss
,如果collection[i]
的[sss[j]
属性的值等于source[sss[j]]
,就先给空数组push
一个0
,代表正确,否则push
一个1
,代表错误。如果这个数组不含有有1,代表这个元素里没有不和source
相等的,那么就把这个collection[i]
push进结果数组,否则只要含有1,就证明含有不等于source
的,那么就不push
,并且重置数组,准备对下一个collection[i]
进行遍历。为了好理解我在纸上画了个图,(估计只有我自己能看清,要是有人看的话我再重新写)
5.查找与替换
使用给定的参数对句子执行一次查找和替换,然后返回新句子。
第一个参数是将要对其执行查找和替换的句子。
第二个参数是将被替换掉的单词(替换前的单词)。
第三个参数用于替换第二个参数(替换后的单词)。
注意:替换时保持原单词的大小写。例如,如果你想用单词 "dog" 替换单词 "Book" ,你应该替换成 "Dog"。
function myReplace(str, before, after) {
var afters = after.charAt(0);
if (before.charAt(0).charCodeAt() < 91) {
afters = afters.toUpperCase();
}
var newAfter = after.replace(after.charAt(0),afters);
return str.replace( before, newAfter);
}
myReplace("Let us go to the store", "store", "mall");
主要还是String.replace() 问题在于大小写的判断,这里用str.charCodeAt()
查询字母在ASCII的编码,A-Z的编码为65-90,a-z的编码为97-122,所以可以加一个判断,如果before
的首字母的ASCII编码小于91,既为大写,那么就把after
的首字母toUpperCase()
,然后利用str.replace()
替换即可
6.儿童黑话
把一个英文单词的第一个辅音或辅音丛(consonant cluster)移到词尾,然后加上后缀 "ay"。
如果单词以元音开始,你只需要在词尾添加 "way" 就可以了。
translate("california")应该返回 "aliforniacay"。
translate("algorithm")应该返回 "algorithmway"。
由于我的英语不太好,分不清什么是辅从音,只好只包含了例子中的。
function translate(str) {
var pig = ["a","e","i","o","u","A","E","I","O","U","g","G"];
var first = str.charAt(0);
if (pig.indexOf(first) < 0) {
return str.substr(1,str.length-1)+str.charAt(0)+"ay";
} else if(str.substr(0,2) == "gl") {
return str.substr(2,str.length-1)+str.substr(0,2)+"ay";
} else return str+ "way";
}
translate("glove");
思路:把所有需要替换的放到一个数组里,然后用str.charAt(0)
获取字符串首字母,再用indexOf()
检查首字母是否再需要替换的数组里,如果是,就对数组进行如下操作:
return str.substr(1,str.length-1)+str.charAt(0)+"ay"
然后再判断是否是辅音丛,因为辅音丛是两个字符,所以就substr(0,2)
截取前两个字符去比较,如果满足做如下操作:
return str.substr(2,str.length-1)+str.substr(0,2)+"ay";
都不满足则返回字符串+way
7.DNA配对
DNA 链缺少配对的碱基。依据每一个碱基,为其找到配对的碱基,然后将结果作为第二个数组返回。
Base pairs(碱基对) 是一对 AT 和 CG,为给定的字母匹配缺失的碱基。
在每一个数组中将给定的字母作为第一个碱基返回。
例如,对于输入的 GCG,相应地返回 [["G", "C"], ["C","G"],["G", "C"]]
字母和与之配对的字母在一个数组内,然后所有数组再被组织起来封装进一个数组。
pair("ATCGA")应该返回 [["A","T"],["T","A"],["C","G"],["G","C"],["A","T"]]。
function pair(str) {
var rel = [];
var bp = {
A: "T",
T: "A",
C: "G",
G: "C"
};
var strarr = str.split("");
for(var i = 0; i<strarr.length; i++) {
rel[i] = [strarr[i]];
rel[i].push(bp[strarr[i]]);
}
return rel;
}
pair("ATCGA");
思路:这个主要是封装进数组不太容易操作。
新建一个对象,里面key
和value
一一对应,y因为传入的是一个字符串,所以先用str.split("")
分割并存为新数组,然后遍历该数组,每个值新建一个数组,再根据key
去对象里找对应的value
push
进这个数组(小数组)就可以得到由几个小数组封装起来的数组了。
8.丢失的信
从传递进来的字母序列中找到缺失的字母并返回它。
如果所有字母都在序列中,返回 undefined。
fearNotLetter("abce")应该返回 "d"。
function fearNotLetter(str) {
var arr = str.split("");
var numarr = [];
for(var i = 0; i<arr.length; i++) {
numarr.push(arr[i].charCodeAt());
}
for(var j = numarr[0]; j<numarr.length+numarr[0]+1; j++) {
if(numarr[j-numarr[0]] != j) {
return String.fromCharCode(j);
} else if (numarr[numarr.length-1] == j) {
return undefined;
}
}
}
fearNotLetter("abce");
思路:将字符串分割后存到新数组,遍历该数组并把每个元素的索引push
到数组2,这样就得到由索引组成的数组,一眼就能看出来哪里少了一个。。。(开个玩笑,计算机可看不出来)
然后对该索引组成的数组遍历,注意起始值设置为该数组的第一个元素,这样能保证遍历的时候 i
正好与索引一一对应,如果哪一个没对应住,就说明这里缺了一个嘛,此时就输出 i
对应的索引准没错,对应程序里就是这一堆,可能不是那么容易理解,关键点在于遍历的起始值,终止值要设置好
for(var j = numarr[0]; j<numarr.length+numarr[0]+1; j++) {
if(numarr[j-numarr[0]] != j) {
return String.fromCharCode(j);
} else if (numarr[numarr.length-1] == j) {
return undefined;
}
}
这里有个坑。。。开始的时候我写如果判断条件满足的话输出索引,否则输出undefined
,乍一看没有错。但是这里是在遍历啊,敲黑板,第一个不满足判断条件直接就输出了好嘛。然后我就想,再判断是否全都对应太麻烦了,那如果只判断最后一个呢?是个好方法啊!因为如果前面不满足直接就return
了,既然能遍历到最后一个,前面肯定没有漏啊,那这样我只需要比较一下最后一个是否满足条件就可以输出了嘛。
9.判断是否是布尔值
检查一个值是否是基本布尔类型,并返回 true 或 false。
基本布尔类型即 true 和 false。
boo(true)应该返回 true。
boo(false)应该返回 true。
boo([1, 2, 3])应该返回 false。
boo(1)应该返回 false。
这是一道送分题啊同学们
function boo(bool) {
return Boolean(bool)===bool?true:false;
}
boo(null);
这里用到了条件操作符,非常好用,基本用法是:
//判断条件 ? 条件为真时的操作 : 条件为假时的操作
//如果Boolean(bool)===bool则返回true,否则返回false
return Boolean(bool)===bool?true:false;
这里要注意要用===
来判断,因为==
会转换类型,比如数字1
会被转换为true
而导致输出结果有误
10.Sorted Union
写一个 function,传入两个或两个以上的数组,返回一个以给定的原始数组排序的不包含重复值的新数组。
换句话说,所有数组中的所有值都应该以原始顺序被包含在内,但是在最终的数组中不包含重复值。
非重复的数字应该以它们原始的顺序排序,但最终的数组不应该以数字顺序排序。
unite([1, 3, 2], [5, 2, 1, 4], [2, 1])应该返回 [1, 3, 2, 5, 4]。
unite([1, 2, 3], [5, 2, 1])应该返回 [1, 2, 3, 5]。
题目不难,因为传入的参数不确定,所以我用了最笨的方法:暴力举穷。。其实可以用arguments
的,以后再更新吧,今天有点懒。。
function unite(arr1, arr2, arr3,arr4) {
for (var i = 0; i<arr2.length; i++) {
if (arr1.indexOf(arr2[i]) < 0) {
arr1.push(arr2[i]);
}
}
if (arr3 !== undefined) {
for (var j = 0; j<arr3.length; j++) {
if (arr1.indexOf(arr3[j]) < 0) {
arr1.push(arr3[j]);
}
}
}
if (arr4 !== undefined) {
for (var k = 0; k<arr4.length; k++) {
if (arr1.indexOf(arr4[k]) < 0) {
arr1.push(arr4[k]);
}
}
}
return arr1;
}
unite([1, 2, 3], [5, 2, 1]);
不要吐槽我。。。