计算字符长度:
function len(s) {
var l = 0;
var a = s.split("");
for (var i = 0; i < a.length; i++) {
if (a[i].charCodeAt(0) < 299) {
l++;
} else {
l += 2;
}
}
return l;
}
删除字符两边的空白、空格
var STR = STR || {
//去掉字符串前后的空格
trim : function(str,pos){
if(pos==='left' || pos==='l' || pos==='L'){
return str.replace(/(^\s*)/, "");
}
if(pos==='right' || pos==='r' || pos==='R'){
return str.replace(/(\s*$)/, "");
}
return str.replace(/(^\s*)|(\s*$)/, "");
}
}
数组去重
方法一
function uniqueArr(array) {
var res={};
var newArr=[];
for(var i=0,l=array.length;i<l;i++) {
if(typeof res[array[i]] == "undefined"){
res[array[i]]=1;
newArr.push(array[i]);
}
}
return newArr;
}
方法二
/**
*去除数组中重复的元素
把元素的值存为一个新数组的key,key是不可以重复的,然后变量次数组即可
*/
function unique(data) {
data = data || [];
var a = {};
len = data.length;
for (var i = 0; i < len; i++) {
var v = data[i];
if (typeof(a[v]) == 'undefined') {
a[v] = 1;
}
};
data.length = 0;
for (var i in a) {
data[data.length] = i;
}
return data;
}
alert(unique([12,12,12,34]));
var arr = [ 1 , 2 , 2 , 3 , ' 5 ' , 6 , 5 , '' , ' ' ]
这个数组只包含了数字,字符串两种类型。我们给数组原型上面添加去重的方法distinct,用第一种很容易想到的方法来实现,当然也是很笨很直接的,把这个数组复制一份然后循环两个数组,对比当前值与后面所有的值是否相等,如果与后面所有值都不等则把该值存到新数组里,如此最后再返回该新数组。方法如下:
// 第一种方法 Array.prototype.distinct = function (){ var clone,newArr = [],n = 0 ; if ( this .length < 2 ) return ; clone = this ; for ( var i = 0 ,len = this .length;i < len;i ++ ){ for ( var j = i + 1 ,len2 = clone.length;j < len2;j ++ ){ if ( this [i] !== clone[j]){ n ++ ; } } if (n == (len - i - 1 )){ newArr.push( this [i]) } n = 0 ; } return newArr; } console.log([ 1 , 2 , 2 , 3 , ' 5 ' , 6 , 5 , '' , ' ' ].distinct());
基本可以满足我们的需求,对这样简单的类型比较确实不用费太多的脑经,但如果数组很长呢?如此遍历数组,数组长度为n,那么时间复杂度为n*n。显然该方法性能还有待提升。接下来是第二种方法,用到数组排序,在排序的过程去除重复的值。
// 第二种方法 Array.prototype.distinct = function (){ var newArr = this .concat().sort(),self = this ; newArr.sort( function (a,b){ var n; if (a === b){ n = self.indexOf(a); self.splice(n, 1 ); } }); return self; } console.log([ 1 , 2 , 2 , 3 , ' 5 ' , 6 , 5 , 6 , 6 , 15 , 5 , ' 5 ' , 5 , '' , ' ' ].distinct());
这样代码看起来似乎短了很多,甚至连一个for循环都没有,但是sort得效率也高不到哪里去。再来看看第三种实现方法,用到的对象属性不会重名的原理
// 第三种方法 Array.prototype.distinct = function (){ var newArr = [],obj = {}; for ( var i = 0 ,len = this .length;i < len;i ++ ){ if ( ! obj[ this [i]]){ newArr.push( this [i]); obj[ this [i]] = ' new ' ; } } return newArr; } console.log([ 1 , 2 , 2 , 3 , ' 5 ' , 6 , 5 , 6 , 6 , 15 , 5 , ' 5 ' , 5 , '' , ' ' ].distinct());
第三种方法运行看下结果,会发现跟上面的方法实现的结果不一致,细看原来它把数字5和字符串5当成重复的值给去掉了。看来类型必须保存起来然后再判断是否相等,这样便有了下面的第三种方法的补充版
// 第三种方法补充版 Array.prototype.distinct = function (){ var newArr = [],obj = {}; for ( var i = 0 ,len = this .length;i < len;i ++ ){ if ( ! obj[ typeof ( this [i]) + this [i]]){ newArr.push( this [i]); obj[ typeof ( this [i]) + this [i]] = ' new ' ; } } return newArr; }
上面举的例子是很简单的类型,我们拿更复杂的类型来测试一下
console.log([ 1 , null , 2 ,{a: ' vc ' },{}, ' 5 ' , 6 , 5 , 6 ,{a: ' vv ' }, 15 , 5 , ' 5 ' , 5 , '' , ' ' ,[1],[1],[1,2],,].distinct());
发现{a:'vc'},{},{a:'vv'}这些不同的对象还是会被剔除掉,如果数组里面有对象则要继续遍历对象里面的属性和值,继续第三种方法的加强
// 第三种方法加强版 Array.prototype.distinct = function (){ var sameObj = function (a,b){ var tag = true ; if ( ! a ||! b) return false ; for ( var x in a){ if ( ! b[x]) return false ; if ( typeof (a[x]) === ' object ' ){ tag = sameObj(a[x],b[x]); } else { if (a[x] !== b[x]) return false ; } } return tag; } var newArr = [],obj = {}; for ( var i = 0 ,len = this .length;i < len;i ++ ){ if ( ! sameObj(obj[ typeof ( this [i]) + this [i]], this [i])){ newArr.push( this [i]); obj[ typeof ( this [i]) + this [i]] = this [i]; } } return newArr; }
用上面的例子测试发现基本木有问题,当然测试还可以更加变态更加纠缠,这里就不去深究了,目前来看此篇方法在网上属于比较齐全的,如果有更好更完善的方法请不吝赐教。
====================================方法四
Array.prototype.uniq = function () {
var arr = [];
var flag = true;
this.forEach(function(item) {
// 排除 NaN (重要!!!)
if (item != item) {
flag && arr.indexOf(item) === -1 ? arr.push(item) : '';
flag = false;
} else {
arr.indexOf(item) === -1 ? arr.push(item) : ''
}
});
return arr;
}
验证:[false, true, undefined, null, NaN, 0, 1, {}, {}, 'a', 'a', NaN].uniq()
方法五(es6)
Array.prototype.uniq = function() {
return Array.from(new Set(this));
}
或者
Array.prototype.uniq = function() {
return [...new Set(this)];
}
删除数组中指定的元素
/**
* 参考实例
foreach = function (obj, insp){
if(obj== null && obj.constructor != Array){
return [];
}
//obj是要处理的数组,obj==null 表示对象尚未存在;obj.constructor != Array 表示对象obj的属性的构造函数不是数组;
//constructor属性始终指向创建当前对象的构造函数。两个条件均满足,则返回空数组[];
//下面对constructor属性作进一步了解。
var obj= [1, 2, 3, 4]; // 等价于 var obj= new Array(1, 2, 3, 4);
console.log(obj.constructor === Array); // 返回true 表明obj的构造函数为Array;
var foo= function() { }; // 等价于 var foo = new Function();
console.log(foo.constructor === Function); // 返回true 表明foo的构造函数为Function;
var obj = new Foo(); //由构造函数实例化一个obj对象
console.log(obj.constructor === Foo); // 返回true 表明obj的构造函数为Foo;
*/
//删除数组中指定的元素
function del(val, arr)
{
//检测参数
if (arr == null && arr.constructor != Array) {
return [];
}
var newarr = []; //不存在的保存到新数组中
for (var i = 0; i < arr.length; i++) {
if (arr[i] != val)
newarr.push(arr[i]);
}
return newarr;
}
alert(del(2, [1, 2, 3, 4, 5, 2]));
删除数组指定下标的元素
/**
*删除数组的指定下标元素
*
* i 的值是一直在变的,n的值是只有if条件成立的时候才会变(会依次递增)
*/
Array.prototype.remove=function(dx)
{
if(isNaN(dx)||dx>this.length){return false;}
for(var i=0,n=0;i<this.length;i++)
{
if(this[i]!=this[dx])
{
this[n++]=this[i]
}
}
this.length-=1
}
var arr = [1,2,3,4,2,5];
alert(arr);
arr.remove(2);
alert(arr);