zoukankan      html  css  js  c++  java
  • 选择器对节点去重的处理

    由于存在并联选择器,因此就算是从右到左过滤结果集,还是存在去重问题。排序问题产说了,以前JK已经给出非常逆天的算法。现在看一下去重问题。其实你们可以看成是一个纯粹的数组去重问题。难度在于速度。因此mootools搞出slickspeed这东西,引发了速度竞赛。现在让我们看看几个去重函数的实现了。

       var unique = function(array) {
            var ret = [];
            o:for(var i = 0, n = array.length; i < n; i++) {
                for(var x = i + 1 ; x < n; x++) {
                    if(array[x] === array[i])
                        continue o; 
                }
                ret.push(array[i]);
            }
            return ret;
        }
     

    这是早期mass Framework的方案,不打乱顺序的

    function uniq(array){
        var ret = [],ri = 0
        array = array.sort();
        ret[ri] = array[0];
         
        for(var j = 1, n = array.length; j < n; j++){
            if(ret[ri] !== array[j]){
                ret[++ri] = array[j]
            }
        }
        return ret;
    }
    

    这是打乱顺序的。

    
     /* 快速除重,相对于ArrayH.unique,为了效率,牺了代码量与严谨性。如果数组里有不可添加属性的对象,则会抛错.
    		 * @method quicklyUnique
    		 * @static
    		 * @param {array} arr 待处理数组
    		 * @return {array} 返回除重后的新数组
    		 */
    		quicklyUnique: function(arr) {
    			var strs = {},
    				numAndBls = {},
    				objs = [],
    				hasNull,
    				hasUndefined,
    				ret = [];
    			for (var i = 0, len = arr.length; i < len; i++) {
    				var oI = arr[i];
    				if (oI === null) {
    					if (!hasNull) {
    						hasNull = true;
    						ret.push(oI);
    					}
    					continue;
    				}
    				if (oI === undefined) {
    					if (!hasUndefined) {
    						hasUndefined = true;
    						ret.push(oI);
    					}
    					continue;
    				}
    				var type = typeof oI;
    				switch (type) {
    				case 'object':
    				case 'function':
    					if (!oI.__4QuicklyUnique) {
    						oI.__4QuicklyUnique = true;
    						ret.push(oI);
    						objs.push(oI);
    					}
    					break;
    				case 'string':
    					if (!strs[oI]) {
    						ret.push(oI);
    						strs[oI] = true;
    					}
    				default:
    					if (!numAndBls[oI]) {
    						ret.push(oI);
    						numAndBls[oI] = true;
    					}
    					break;
    				}
    			}
    			for (i = 0; oI = objs[i++];) {
    				if (oI instanceof Object) {
    					delete oI.__4QuicklyUnique;
    				} else {
    					oI.__4QuicklyUnique = undefined;
    				}
    			}
    			return ret;
    		},
    

    这是qwrap框架提供的方案,利用经典的hash去重法,但这要对对象类型的元素做些手段,因此它只是候选放案。像网上那些流行的普通hash去重法更是经不起推敲。

    	unique: function(arr) {
    			var rlt = [],
    				oI = null,
    				indexOf = Array.indexOf || ArrayH.indexOf;
    			for (var i = 0, len = arr.length; i < len; i++) {
    				if (indexOf(rlt, oI = arr[i]) < 0) {
    					rlt.push(oI);
    				}
    			}
    			return rlt;
    		},
    

    这是qwrap现时的方案,运用原生Array.prototype.indexOf,不支持需要自己做个轮子。

            unique: function ( target ) {
                var ret = [], n = target.length, i, j;
                for (i = 0; i < n; i++) {
                    for (j = i + 1; j < n; j++)
                        if (target[i] === target[j])
                            j = ++i;
                    ret.push(target[i]);
                }
                return ret;
            },
    

    这是mass Framework正在采用的方案,由群里的abcd提供。

    Sizzle.uniqueSort = function( results ) {
    	if ( sortOrder ) {
    		hasDuplicate = baseHasDuplicate;
    		results.sort( sortOrder );
    
    		if ( hasDuplicate ) {
    			for ( var i = 1; i < results.length; i++ ) {
    				if ( results[i] === results[ i - 1 ] ) {
    					results.splice( i--, 1 );
    				}
    			}
    		}
    	}
    
    	return results;
    };
    

    这是 jQuery 1.7 前的方案,直接在原数组上操作,如果数组很大,会容易搞死IE6。由于处理的是节点,要保持像querySelectorAll那样的效果,需要按DOM树出现顺序重排。

    
    Sizzle.uniqueSort = function( results ) {
    	var elem,
    		i = 1;
    
    	hasDuplicate = baseHasDuplicate;
    	results.sort( sortOrder );
    
    	if ( hasDuplicate ) {
    		for ( ; (elem = results[i]); i++ ) {
    			if ( elem === results[ i - 1 ] ) {
    				results.splice( i--, 1 );
    			}
    		}
    	}
    
    	return results;
    };
    

    jquery1.8的实现,它不再访问数组的 length 属性,提高了运行效率。每次以 elem = results[i] 赋值后是否存在为循环判定条件。

    Sizzle.uniqueSort = function( results ) {
    	var elem,
    		duplicates = [],
    		i = 1,
    		j = 0;
    
    	hasDuplicate = baseHasDuplicate;
    	results.sort( sortOrder );
    
    	if ( hasDuplicate ) {
    		for ( ; (elem = results[i]); i++ ) {
    			if ( elem === results[ i - 1 ] ) {
    				j = duplicates.push( i );
    			}
    		}
    		while ( j-- ) {
    			results.splice( duplicates[ j ], 1 );
    		}
    	}
    
    	return results;
    };
    

    jquery1.83的实现,它是先保持了索引值,然后从后面开始删除,避免数组索引的改动导致删除错误。

    但明显jquery.unique不能用于普通的数组去重。因此在mass Framework它们是不相干的两个函数。

    机器瞎学/数据掩埋/模式混淆/人工智障/深度遗忘/神经掉线/计算机幻觉/专注单身二十五年
  • 相关阅读:
    dropdownlist下拉框加--请选择---
    vs2012中自带IIS如何让其他电脑访问
    win7 web开发遇到的问题-由于权限不足而无法读取配置文件,无法访问请求的页面
    无法打开登录所请求的数据库 "xxxx"。登录失败。 用户 'NT AUTHORITYSYSTEM' 登录失败。
    如何实现删除确认
    如何获取GridView的总记录数?
    SQL两张表如何关联
    ES7学习笔记——Array.prototype.includes和求幂运算符**
    一些常用的JavaScript正则表达式
    Vue.js 2.x中事件总线(EvevntBus)及element-ui中全屏loading的使用
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/2817654.html
Copyright © 2011-2022 走看看