freeCodeCamp
1.翻转字符串
function reverseString(str) {
var arr = str.split("").reverse();
str = arr.join("");
return str;
}
reverseString("hello");
2.实现阶乘
function factorialize(num) {
var newNum =1;
for(var i=1;i<=num;i++){
newNum *= i;
}
num = newNum;
return num;
}
factorialize(5);
3.判断回文字符串
即字符从左到右和从右到左都是一样的****。
function palindrome(str) {
str=str.replace(/\W|\s|_/ig,'');
return str.toLowerCase() == str.split('').reverse().join('').toLowerCase();
}
palindrome("eye");
4.返回字符串中最长的单词长度
function findLongestWord(str) {
var arr = str.split(" "),
len=arr[0].length;
for(var i=0;i<arr.length;i++){
if(len<arr[i].length){
len=arr[i].length;
}
}
return len;
}
findLongestWord("Google do a barrel roll");
5.返回字符串中首字母大写
var a = 'Hi, my name\'s Han Meimei, a SOFTWARE engineer';
//for循环
function titleCase(s) {
var i, ss = s.toLowerCase().split(/\s+/);
for (i = 0; i < ss.length; i++) {
ss[i] = ss[i].slice(0, 1).toUpperCase() + ss[i].slice(1);
}
return ss.join(' ');
}
console.log(titleCase(a));
6.查找多个数组中的最大值,并返回最大值数组
function largestOfFour(arr) {
var newArr = new Array();
for(var i=0;i<arr.length;i++){
newArr[i] = arr[i][0];
for(var j=0;j<arr[i].length;j++){
if(newArr[i]<arr[i][j]){
newArr[i] = arr[i][j];
}
}
}
return newArr;
}
largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);
7.截断字符串
function truncate(str, num) {
var len = str.length;
if(len > num){
if(num>3)
str = str.slice(0,num-3)+"...";
else
str = str.slice(0,num)+"...";
}
return str;
}
truncate("A-tisket a-tasket A green and yellow basket", 11);
8.分割数组,将原一维数组分割成二维数组。
function chunk(arr, size) {
var newArr = [];
var j=0;
for(var i=0;i<arr.length/size;i++){
newArr[i]=arr.slice(j,j+size);
j+=size;
}
return newArr;
}
chunk(["a", "b", "c", "d"], 2);
方法二:
function chunk(arr, size) {
var newArr=[];
for(i=0;i<arr.length;i+=size){
newArr.push(arr.slice(i,i+size));
}
return newArr;
}
chunk(["a", "b", "c", "d"], 2);
9.截断数组,返回一个数组被截断n个元素后还剩余的元素,截断从索引0开始。
function slasher(arr, howMany) {
return arr.splice(0,howMany);
}
slasher([1, 2, 3], 2);
10.比较字符串,包含问题
若第一个字符串包含第二个字符串,返回true,反之,返回false。
方法一:
function mutation(arr) {
arr[1]=arr[1].toLowerCase().split('');
var flag =[];
for(var i=0;i<arr[1].length;i++){
flag[i] =arr[0].toLowerCase().indexOf(arr[1][i]);
}
return flag.every(function(e){
return e > -1;
});
}
mutation(["hello", "hey"]);
方法二:(简化方法一)
arr[1]=arr[1].toLowerCase().split('');
return arr[1].every(function(e){
return arr[0].toLowerCase().indexOf(e)>-1;
});
11.过滤数组假值,删除数组中的所有假值。
在JavaScript中,假值有false、null、0、””、undefined 和 NaN。
function bouncer(arr) {
return arr.filter(function(e){
return e;
});
}
bouncer([7, "ate", "", false, 9]);
12.摧毁数组
function destroyer(arr) {
var args = [];
for(var i = 1; i < arguments.length; i++){
//arguments表示函数参数输入值,将待摧毁的值放入一个数组中,赋值给变量args
args.push(arguments[i]);
}
var newArr=arr.filter(function(item){ //两个数组去重;
return args.indexOf(item) === -1;
});
return newArr;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
13.数组排序并找出元素索引,
先给数组排序,然后找到指定的值在数组的位置,最后返回位置对应的索引。
function where(arr, num) {
if(arr.indexOf(num)<0){
arr.push(num);
}
arr.sort(function(a,b){
return a-b;
});
return arr.indexOf(num);
}
where([3, 10, 5], 3);
14.移位密码,字母会按照指定的数量来做移位。
所有的字母都是大写,不要转化任何非字母形式的字符(例如:空格,标点符号),遇到这些特殊字符,跳过它们。
function rot13(str) {
var arr=[];
var A = 'A'.charCodeAt(), Z = 'Z'.charCodeAt();
var code;
for(var i=0;i<str.length;i++){
code = str[i].charCodeAt();
if(code >= A && str[i].charCodeAt() <= Z){
if(code < A+13){
arr.push(String.fromCharCode(code+13));
}else{
arr.push(String.fromCharCode(code-13));
}
}else{
arr.push(String.fromCharCode(code));
}
}
return arr.join("");
}
rot13("SERR PBQR PNZC");
15.区间累加求值
返回这两个数字和它们之间所有数字的和。
function sumAll(arr) {
arr.sort(function(a,b){
return a-b;
});
var min=arr[0],max=arr[arr.length-1];
var sum=0;
for(var i=min;i<=max;i++){
sum+=min;
min++;
}
return sum;
}
sumAll([1, 4]);
16.返回两个数组的不同值
返回两个数组的差异。
function diff(arr1, arr2) {
var newArr = [];
newArr=arr1.concat(arr2).filter(function(e){
return arr1.indexOf(e)==-1||arr2.indexOf(e)==-1;
});
return newArr;
}
diff([1, 2, 3, 5], [1, 2, 3, 4, 5]);
17.匹配数组中的对象,返回匹配的值
function where(collection, source) {
var arr = [];
var sourcePro = Object.keys(source);
var flag = 0,pro;
for(var i=0;i<collection.length;i++){
for(var j=0;j<sourcePro.length;j++){
pro = sourcePro[j];
if(collection[i].hasOwnProperty(pro)){
if(collection[i][pro]==source[pro]){
flag = 1;
}/*else{flag = 0; }*/
}else{flag = 0; }
}
if(flag == 1){
arr.push(collection[i]);
}
}
return arr;
}
where([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });
18.搜索替换,
使用给定的参数对句子执行一次查找和替换,然后返回新句子。第一个参数是将要对其执行查找和替换的句子。第二个参数是将被替换掉的单词(替换前的单词)。第三个参数用于替换第二个参数(替换后的单词)。
function myReplace(str, before, after) {
var arr=str.split(" ");
for(var i=0;i<arr.length;i++){
if(arr[i]==before){
if(/[a-z]/.test(before.slice(0,1))){//判断首字母是否大写
arr.splice(i,1,after.toLowerCase());
}else{
after=after.replace(after.slice(0,1),after.slice(0,1).toUpperCase());
arr.splice(i,1,after);
}
}
}
str = arr.join(" ");
return str;
}
myReplace("A quick brown fox jumped over the lazy dog", "jumped", "leaped");
19.字符串移动插入算法,
把一个英文单词的第一个辅音或辅音丛(consonant cluster)移到词尾,然后加上后缀 “ay”。如果单词以元音开始,你只需要在词尾添加 “way” 就可以了。输入字符串保证是英文单词全部小写。
function translate(str) {
var latin=["a","o","e","i","u"];
var arr = str.toLowerCase().split("");
var a = 0,b=0,flag;
for(var i=0;i<latin.length;i++){
if(arr[0].indexOf(latin[i])>-1)
a = 1;
if(arr[1].indexOf(latin[i])>-1)
b = 1;
}
if(a == 0 && b == 0){
arr.push(arr[0]+arr[1]+"ay");arr.shift();arr.shift();
}else if(a == 1){
arr.push("way");
}else if(a==0 && b == 1){
arr.push(arr[0]+"ay");arr.shift();
}
str = arr.join("");
return str;
}
translate("glove");
20.DNA 链缺少配对的碱基。
依据每一个碱基,为其找到配对的碱基,然后将结果作为第二个数组返回。Base pairs(碱基对) 是一对 AT 和 CG,为给定的字母匹配缺失的碱基。
function pair(str) {
var arr = str.split("");
var newArr = [];
for(var i=0;i<arr.length;i++){
switch(arr[i]){
case "G" : newArr[i]=["G","C"];break;
case "C" : newArr[i]=["C","G"];break;
case "A" : newArr[i]=["A","T"];break;
case "T" : newArr[i]=["T","A"];break;
}
}
return newArr;
}
pair("GCG");
21.字符串查询补充算法。
从传递进来的字母序列中找到缺失的字母并返回它。如果所有字母都在序列中,返回 undefined。
function fearNotLetter(str) {
var code = str[0].charCodeAt();
var newStr = undefined;
for(var i=0;i<str.length;i++){
if(str[i] != String.fromCharCode(code)){
newStr = String.fromCharCode(code);
code++;
}
code++;
}
return newStr;
}
fearNotLetter("bcd");
22.数据类型检查算法,
检查一个值是否是基本布尔类型,并返回 true 或 false。
function boo(bool) {
return typeof bool=="boolean";
}
boo(null);
23.多个数组去重算法
传入两个或两个以上的数组,返回一个以给定的原始数组排序的不包含重复值的新数组。
function unite(arr1, arr2, arr3) {
var args = [];
for(var i=0;i<arguments.length;i++){
args.push(arguments[i]);
}
args = args.reduce(function(a,b){
return a.concat(b);
});
args = args.filter(function(e,index,args){
return args.indexOf(e)===index;
});
return args;
}
unite([1, 3, 2], [5, 2, 1, 4], [2, 1]);
24.html符号转实体算法,
将字符串中的字符 &、<、>、” (双引号), 以及 ‘ (单引号)转换为它们对应的 HTML 实体。
function convert(str) {
var regObj = {
"&":"&","<":"<",">":">",'"':""","'":"'"
};
var reg = /[&<>"']/g;
var arr = str.match(reg);
if(arr){
for(var i in arr){
str = str.replace(arr[i],regObj[arr[i]]);
}
}
return str;
}
convert("Hamburgers < Pizza < Tacos");
25.字符串连接算法
将字符串转换为 spinal case ,Spinal case 是 all-lowercase-words-joined-by-dashes 这种形式的,也就是以连字符连接所有小写单词。
function spinalCase(str) {
var reg1 = /[\W_]/g;
var reg2 = /[A-Z]/g;
var arr = str.match(reg1);
var arr2 = str.match(reg2);
if(arr != null){
for(var i in arr)
str = str.replace(arr[i],"-").toLowerCase();
}
if(arr2 != null){
for(var i in arr2)
str = str.replace(arr2[i],"-"+arr2[i].toLowerCase());
}
return str;
}
spinalCase('thisIsSpinalTap');
26.计算斐波那契奇数和
给一个正整数num,返回小于或等于num的斐波纳契奇数之和。
function sumFibs(num) {
var cache = [1, 1];
if (num >= cache.length) {
for (var i = cache.length; i < num ; i++ ) {
cache[i] = cache[i - 2] + cache[i - 1];
}
}
var arr=cache.filter(function(val){
return val%2!==0&&val<=num;
});
return arr.reduce(function(pre,next){
return pre+next;
});
}
sumFibs(4);
27.求小于等于给定数值的质数之和。
function sumPrimes(num) {
var sum=0;
for (var i=2; i <= num; i++) {
var isPN=true;
for(var j=2;j<i;j++){
if(i%j == 0){
isPN=false;
break;
}
}
if(isPN) sum+=i;
}
return sum;
}
sumPrimes(10);
28.欧几里得算法(最小公倍数)
找出能被两个给定参数和它们之间的连续数字整除的最小公倍数。(欧几里得算法)
function smallestCommons(arr) {
arr=arr.sort(function(a,b){
return a-b;
});
var num=arr[0];
for(var i= arr[0]+1;i<=arr[1];i++){
num*=i/gcd(num,i);
}
return num;
}
function gcd(m,n){
if(m%n===0)return n;
return gcd(n,m%n);
}
smallestCommons([1,5]);
29.返回参数数组中第一个满足参数函数 func 返回值的元素。
function find(arr, func) {
var num = arr.filter(func)[0];
return num;
}
find([1, 2, 3, 4], function(num){ return num % 2 === 0; });
30.丢弃数组(arr)的元素,
从左边开始,直到回调函数return true就停止。
function drop(arr, func) {
while (!func(arr[0])) {
arr.shift();
}
return arr;
}
drop([1, 2, 3], function(n) {return n < 3; });
31.对嵌套的数组进行扁平化处理。
function steamroller(arr) {
return arr.reduce(function(prev,item){
return prev.concat(Array.isArray(item)?steamroller(item):item);
},[]);
}
steamroller([1, [2], [3, [[4]]]]);
32.传入二进制字符串,翻译成英语句子并返回。
function binaryAgent(str) {
var arr = str.split(" ");
arr = arr.map(function(e){
return String.fromCharCode(parseInt(e,2));
});
return arr.join("");
}
binaryAgent("01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111");
33.数组元素判断
如果集合(collection)中的所有对象都存在对应的属性(pre),并且属性(pre)对应的值为真。函数返回ture。反之,返回false。
function every(collection, pre) {
// Is everyone being true?
return collection.every(function(e){
return e[pre];
});
}
every([{"user": "Tinky-Winky", "sex": "male"}, {"user": "Dipsy", "sex": "male"}, {"user": "Laa-Laa", "sex": "female"}, {"user": "Po", "sex": "female"}], "sex");
34.函数迭代参数求和
创建一个计算两个参数之和的 function。如果只有一个参数,则返回一个 function,该 function 请求一个参数然后返回求和的结果。
function add() {
var arr = Array.prototype.slice.call(arguments);
if(arr.length === 2){
if(Number.isFinite(arr[0]) && Number.isFinite(arr[1])){
return arr[0]+arr[1];
}else{
return undefined;
}
}else{
if(Number.isFinite(arr[0])){
return function(b){
if(Number.isFinite(b)){
return arr[0]+b;
}else{
return undefined;
}
};
}else{
return undefined;
}
}
return false;
}
add(2,3);
35. 电话正则检测
如果传入字符串是一个有效的美国电话号码,则返回 true.
function telephoneCheck(str) {
var reg = /^1? ?(\(\d{3}\)|\d{3})[ |-]?\d{3}[ |-]?\d{4}$/g;
return reg.test(str);
}
telephoneCheck("555-555-5555");
在线正则表达式检测:http://tool.oschina.net/regex
36. 对等差分
创建一个函数,接受两个或多个数组,返回所给数组的对等差分(△ or ⊕)数组.
function sym(args) {
var arr=[];
for(var i =0;i<arguments.length;i++){
arr.push(arguments[i]);
}
var temp = arr.reduce(function(prev,cur,index,array){
var a = prev.filter(function(item){
return cur.indexOf(item) < 0;
});
var b = cur.filter(function(item){
return prev.indexOf(item) < 0;
});
return a.concat(b);
});
return temp.filter(function(item,index,array){
return array.indexOf(item) == index;
});
}
sym([1, 2, 3], [5, 2, 1, 4]);
37. 收银程序,找零算法
其把购买价格(price)作为第一个参数 , 付款金额 (cash)作为第二个参数, 和收银机中零钱 (cid) 作为第三个参数.
参考博客:https://www.cnblogs.com/suifengershi/p/7442811.html
function checkCashRegister(price, cash, cid) {
var change;
change = cash - price;//找的钱
var arr = [];var j=0;
var array = [0.01,0.05,0.1,0.25,1,5,10,20,100];//对应cid[i][0]
var total = 0;var money = change;
for(var i=cid.length-1;i>=0;i--){
total += cid[i][1];//总钱数
//cid[i][0]:PENNY单位,cid[i][1]:1.01总数
if(change > array[i] && cid[i][1]>0){//
var c = parseInt(change/array[i]);//可以找多少张这个钱
//如果change中可以找的这个钱的金额,比实际这个金额的钱大,说明可以将现有的钱找完,cid[i]应该放到数组中
//如果小,则将change可以找的金额放进去
if(c*array[i] > cid[i][1]){
change -= cid[i][1];
}else{
change -= c*array[i];
cid[i][1] = c*array[i];
}
change = change.toFixed(2);//四舍五入,保留两位小数
//arr.push(cid[i]);
arr[j] = cid[i];
j++;
}
}
if(total == money){//总钱数等于要找的钱,closed
return "Closed";
}else if(total < money || change != 0){//总钱数小于要找的钱,或者不能找整
return "Insufficient Funds";
}
return arr;
}
// Example cash-in-drawer array:
// [["PENNY", 1.01],
// ["NICKEL", 2.05],
// ["DIME", 3.10],
// ["QUARTER", 4.25],
// ["ONE", 90.00],
// ["FIVE", 55.00],
// ["TEN", 20.00],
// ["TWENTY", 60.00],
// ["ONE HUNDRED", 100.00]]
checkCashRegister(19.50, 20.00, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.10], ["QUARTER", 4.25], ["ONE", 90.00], ["FIVE", 55.00], ["TEN", 20.00], ["TWENTY", 60.00], ["ONE HUNDRED", 100.00]]);
38.库存更新
依照一个存着新进货物的二维数组,更新存着现有库存(在 arr1 中)的二维数组. 如果货物已存在则更新数量 . 如果没有对应货物则把其加入到数组中,更新最新的数量. 返回当前的库存数组,且按货物名称的字母顺序排列.
function updateInventory(arr1, arr2) {
var array1=[],array2=[];
for(var i=0;i<arr1.length;i++){
array1.push(arr1[i][1]);
}
for(var j=0;j<arr2.length;j++){
array2.push(arr2[j][1]);
}
array1=array1.concat(array2);
array2=array1.filter(function(e,index,array1){
return array1.indexOf(e) !==index;
});
var curNum;
for(i=0;i<array2.length;i++){
for(j=0;j<arr1.length;j++){
if(arr1[j][1]==array2[i]){
curNum = arr1[j][0];
arr1.splice(j,1);
}
}
for(j=0;j<arr2.length;j++){
if(arr2[j][1]==array2[i]){
arr2[j][0]+=curNum;
}
}
}
arr1=arr1.concat(arr2).sort(function(a,b){
return a[1].localeCompare(b[1]);
});
return arr1;
}
// 仓库库存示例
var curInv = [[21, "Bowling Ball"], [2, "Dirty Sock"], [1, "Hair Pin"], [5, "Microphone"]];
var newInv = [[2, "Hair Pin"], [3, "Half-Eaten Apple"], [67, "Bowling Ball"], [7, "Toothpaste"]];
updateInventory(curInv, newInv);
39.链表
由一组结点组成的集合,每个结点都使用一个对象的引用指向它的后继,指向另一个结点的引用叫做链。链表一般有一个头结点。
①创建链表
function LinkedList() {
var Node = function(element) {
this.element = element;
this.next = null;
}
//其他方法
}
②向链表尾部添加元素
列表为空,添加的是第一个元素。列表不为空,向其追加元素。要循环访问列表中的所有元素,就需要有一个起点,就是head。
this.append = function(element) {
var node = new Node(element), //传入值创建Node项
current;
if(head === null) { //如果为空链表
head = node; //设置node为head(head为第一个节点的引用)
} else {
current = head; //从表头开始
while(current.next) {
//循环列表,找到最后一项(列表最后一个节点的下一个元素始终是null)
current = current.next;
}
//使当前最后一项的指针指向node
current.next = node;
}
length++; //更新列表长度
};
// 使用append
var list = new LinkedList();
list.append(15);
list.append(10);
③从链表移除元素
输入位置,从特定的位置移除元素
this.removeAt = function(position) {
if(position > -1 && position < length) { //有效性检测
var current = head, //用current来循环列表
previous,
index = 0;
if(position === 0) {
head = current.next; //移除第一个元素,直接把head指向下一个元素
} else {
while(index++ < position) { //循环列表找到满足条件的那个元素
previous = current; //
current = current.next; //把下一个变量覆给current
}
//跳过current,将当前要移除的元素的上一个与下一项直接连接起来。
previous.next = current.next;
}
length --;
return current.element;
} else {
return null;
}
}
④在任意位置插入元素
this.insert = function (position, element) {
if(position >= 0 && position <= length) {
var node = new Node(element),
current = head; //通过current从head位置开始迭代
previous,
index = 0;
if(position === 0) { //第一个位置
node.next = current; //此时current = head,指向head那么node就成了第一个
head = node; //node指向为head
} else {
while (index++ < position ) { //循环迭代到目标位置
previous = current;
current = current.next;
}
node.next = current; // node的下一个为current
previous.next = node; // node的上一个位置为previous
}
length++;
return true;
} else {
return false;
}
}
⑤把LinkedList对象转换成字符串
this.toString = function() {
var current = head,
string = '';
while(current) { //循环访问列表
string += current.element + (current.next ? '\n' : '');
current = current.next;
}
return string; //返回字符串
}
⑥返回元素的位置
this.indexOf = function(element) {
var current = head,
index = 0;
while(current) {
if(element === current.element) {
return index; //找到返回当前位置
}
index ++;
current = current.next;
}
return -1; //找不到返回-1
}
⑦输入元素,移除该元素
this.remove = function(element) {
var index = this.indexOf(element); //得到元素的位置
return this.removeAt(index); //移除该元素
}
⑧判断是否为空
this.isEmpty = function () {
return length === 0;
}
⑨获取链表长度
this.size = function () {
return length;
}
⑩获取第一个元素
this.getHead = function () {
return head;
}
40.双向链表
在双向链表中,链接是双向的,一个链向下一个元素一个链向上一个元素。在操作双向链表的时候既要像普通链表一样考虑next,也要考虑prev。双向列表提供了两种迭代列表的方法:从头到尾迭代,或者反过来。
① 创建双向链表
function DoublyLinkedList() {
var Node = function(element) {
this.element = element;
this.next = null;
this.prev = null; //新指针
};
var length = 0;
var head = null;
var tail = null; //对列表最后一项的引用
//各种方法
}
② 在任意位置插入一个新元素
this.insert = function(position, element) {
if(position >= 0 && position <= length) {
var node = new Node(element),
current = head,
previous,
index = 0;
if(position === 0) { //在第一个位置添加
if(!head) { //如果head不存在即链表为空
head = node;
tail = node;
} else { //链表不为空
node.next = current;
current.prev = node;
head = node;
}
} else if(position === length) { //在最后一个位置添加
current = tail;
current.next = node;
node.prev = current;
tail = node;
} else {
while(index++ < position) { //在列表中间添加
previous = current; //循环迭代
current = current.next;
}
node.next = current;
previous.next = node;
current.prev = node;
node.prev = previous;
}
length ++; //更新列表长度
return true;
} else {
return false;
}
}
③ 从任意位置移除新元素
this.removeAt = function(position) {
if(position > -1 && position < length) { //检查越界值
var current = head,
previous,
index = 0;
if(position === 0) { //第一个位置
head = current.next;
if(length === 1) { //如果链表只有一项
tail = null;
} else { //也就相当于把current.next.prev = null
head.prev = null;
}
} else if(position === length -1) { //最后一项
current = tail; //tail的引用赋给current变量
tail = current.prev; //上一项指向tail
tail.next = null; //最后一项的next都是指向null的
} else {
while(index++ < position) { //从中间位置移除
previous = current;
current = current.next;
}
previous.next = current.next; //直接跳过current连接上一项和下一项
current.next.prev = previous;
}
length --;
return current.element;
} else {
return null;
}
}
41.求最长公共子串
function find(str1,str2){
var shorter, longer;
if(str1.length>str2.length){
shorter = str2; longer = str1
}else{
shorter = str1; longer = str2;
}
for(var subLength = shorter.length;subLength>0;subLength--){
//先从第一个字符到最后一个字符检测,再从第一个字符到倒数第二个字符开始检测
for(var i = 0;i+subLength<=shorter.length;i++){
//先从第一个字符到最后一个字符检测,再从第二个字符到最后一个字符检测
var subString =shorter.substring(i,i+subLength);
if(longer.indexOf(subString)>=0){
targetString = subString;
return targetString;
}
}
}
}
find("intesting","string");
42.找出数组中重复元素,并升序输出
//另一种解题思路,利用正则表达式求出相同数据的长度>1则重复。
function duplicates(arr) {
var arrNew=[];
for(var i=0;i<arr.length;i++){
if(arr.indexOf(arr[i])!=arr.lastIndexOf(arr[i])){
arrNew.push(arr[i]);
}
}
arrNew = arrNew.filter(function(a,index,arrNew){
return arrNew.indexOf(a)==index;
});
arrNew = arrNew.sort(function(a,b){
return a-b;
});
return arrNew;
}