惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V2EX - 技术
V2EX - 技术
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Latest news
Latest news
T
The Exploit Database - CXSecurity.com
博客园 - 三生石上(FineUI控件)
WordPress大学
WordPress大学
L
Lohrmann on Cybersecurity
aimingoo的专栏
aimingoo的专栏
B
Blog
T
Threat Research - Cisco Blogs
罗磊的独立博客
Application and Cybersecurity Blog
Application and Cybersecurity Blog
P
Proofpoint News Feed
P
Palo Alto Networks Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
宝玉的分享
宝玉的分享
博客园 - 司徒正美
Google DeepMind News
Google DeepMind News
Blog — PlanetScale
Blog — PlanetScale
T
Tor Project blog
阮一峰的网络日志
阮一峰的网络日志
Last Week in AI
Last Week in AI
Martin Fowler
Martin Fowler
酷 壳 – CoolShell
酷 壳 – CoolShell
Recorded Future
Recorded Future
D
DataBreaches.Net
Y
Y Combinator Blog
大猫的无限游戏
大猫的无限游戏
IT之家
IT之家
B
Blog RSS Feed
Scott Helme
Scott Helme
P
Proofpoint News Feed
V
Vulnerabilities – Threatpost
A
Arctic Wolf
Help Net Security
Help Net Security
L
LINUX DO - 最新话题
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Vercel News
Vercel News
AWS News Blog
AWS News Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
S
Schneier on Security
Hacker News: Ask HN
Hacker News: Ask HN
N
Netflix TechBlog - Medium
L
LangChain Blog
博客园 - 叶小钗
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
M
MIT News - Artificial intelligence
N
News and Events Feed by Topic
Webroot Blog
Webroot Blog
W
WeLiveSecurity

博客园 - 浙林龙哥

S3 put object upload file,被AI欺骗的一天 How to get blob data using javascript XmlHttpRequest by sync 咖啡之约--体验 SourceAnywhere 安装node.js / npm / express / KMC 选择沃阁橱柜 ASP.NET 4.0的ClientIDMode=”Static”未必是最好 VS 2010 和 .NET 4.0 系列之《ASP.NET 4 Web Forms 的整洁HTML标识 — 客户端ID》篇 .NET 3.5 Ruby学习1-字符串 ImageMagick 详细安装使用 linux (jmagick) Windows XP 上安装 Bind9 BIND9配置 [javascript]数组去重 数组A和B找交集 淘宝图片空间---设计师可免费申请短链接啦! php框架 How to use iBatis/NHibernate in medium trust/partial trust environments like Mosso JVM调优 常用的eclipse plugins
[javascript] 数组去重问题
浙林龙哥 · 2011-03-08 · via 博客园 - 浙林龙哥

很经典的问题,去除数组中的重复元素,上网搜了一下,发现大多数无论转载还是原创都是这个解法:

错误解法:

Js代码 复制代码 收藏代码

  1. function uniq(array) {   
  2.     var map={};    
  3.     var re=[];    
  4.     for(var i=0,l=array.length;i<l;i++) {    
  5.         if(typeof map[array[i]] == "undefined"){    
  6.             map[array[i]]=1;   
  7.             re.push(array[i]);   
  8.         }   
  9.     }   
  10.     return re;    
  11. }  
function uniq(array) {
	var map={};
	var re=[];
	for(var i=0,l=array.length;i<l;i++) {
		if(typeof map[array[i]] == "undefined"){
			map[array[i]]=1;
			re.push(array[i]);
		}
	}
	return re;
}

如果用过java等高级语言的话,初看这段代码确实没有什么问题:下面的例子:

Js代码 复制代码 收藏代码

  1. uniq([1,2,1,2,4]);  
uniq([1,2,1,2,4]);

也能正常运行。

可再试试下面的例子:

Js代码 复制代码 收藏代码

  1. uniq([{x:1},"[object Object]"]);   
  2. uniq([{x:1},{z:2}]);  
uniq([{x:1},"[object Object]"]);
uniq([{x:1},{z:2}]);
 

运行一下就会知道错在哪里了!

HashMap In Java :

在 java 中如 HashMap 类可以使用对象做为 key (内部实现使用 hashcode散列到桶 以及桶内equals[默认内存地址]比较),如:

Java代码 复制代码 收藏代码

  1. class Holder {   
  2.     int i;   
  3. }   
  4.  public class Test3 {   
  5.   
  6.      
  7.  
  8.   
  9.     public static void main(String[] args) {   
  10.         HashMap<Holder, Holder> map=new HashMap<Holder, Holder>();   
  11.         Holder key= new Holder();   
  12.         Holder value= new Holder();   
  13.         value.i=1;   
  14.         map.put(key, value);   
  15.         Holder key2=new Holder();    
  16.         System.out.println(map.get(key).i);   
  17.         System.out.println(map.get(key2));   
  18.     }   
  19.   
  20. }  
class Holder {
	int i;
}
public class Test3 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		HashMap<Holder, Holder> map=new HashMap<Holder, Holder>();
		Holder key= new Holder();
		Holder value= new Holder();
		value.i=1;
		map.put(key, value);
		Holder key2=new Holder(); 
		System.out.println(map.get(key).i);
		System.out.println(map.get(key2));
	}

}

Object In Javascript:

而在 javascript 中毕竟没有map,只有对象这个概念,而对象则要求其属性值必须为字符串,如果提供给对象的属性不是字符串,那么则会自动调用 toString 方法转化为字符串形式,例如:

Js代码 复制代码 收藏代码

  1. var x={};   
  2.  var y={   
  3.     toString:function(){   
  4.         return "z";   
  5.      }   
  6. };   
  7.   
  8. x[y]=1;   
  9. alert(x["z"]);  
var x={};
var y={
    toString:function(){
        return "z";
     }
};

x[y]=1;
alert(x["z"]);

那么由上述例子就可以知道第一个程序为什么是错误的了 。

正确答案:

我们无法利用高级语言提供的map类库,那就只好两遍遍历数组了,也是 taobao ued提供的标准答案:

注意 === 使用。

Js代码 复制代码 收藏代码

  1.  
  2.  
  3.  
  4.  
  5.   
  6.  function undulpicate(array){   
  7.     for(var i=0;i<array.length;i++) {   
  8.         for(var j=i+1;j<array.length;j++) {   
  9.               
  10.             if(array[i]===array[j]) {   
  11.                 array.splice(j,1);   
  12.                 j--;   
  13.             }   
  14.         }   
  15.     }   
  16.     return array;   
  17. }  
/**
*unique the array
*@param {Array} array array to unique
*@return {Array} uniqued array ,note change parameter
*/
function undulpicate(array){
	for(var i=0;i<array.length;i++) {
		for(var j=i+1;j<array.length;j++) {
			//注意 ===
			if(array[i]===array[j]) {
				array.splice(j,1);
				j--;
			}
		}
	}
	return array;
}
 

ps: Jquery Uniq Node

如果我们确认数组里每个元素都是对象,那么可以用加标签的方式,给对象元素添加标签,从而把时间复杂度提升到 O(n) :

Js代码 复制代码 收藏代码

  1. var x={z:1};   
  2.  var y={q:2};   
  3.  function uniqObjects(array){   
  4.     var re=[];   
  5.     for(var i=0,l=array.length;i<l;i++) {   
  6.         if(typeof array[i]["_uniqObjects"] == "undefined"){   
  7.               
  8.                         array[i]["_uniqObjects"]=1;   
  9.             re.push(array[i]);   
  10.         }   
  11.     }   
  12.           
  13.     for(var i=0,l=re.length;i<l;i++) {   
  14.         delete re[i]["_uniqObjects"];   
  15.     }   
  16.     return re;   
  17. }   
  18. uniqObjects([x,y,x]);  
var x={z:1};
var y={q:2};
function uniqObjects(array){
	var re=[];
	for(var i=0,l=array.length;i<l;i++) {
		if(typeof array[i]["_uniqObjects"] == "undefined"){
			//添加标签
                        array[i]["_uniqObjects"]=1;
			re.push(array[i]);
		}
	}
        //取出标签
	for(var i=0,l=re.length;i<l;i++) {
		delete re[i]["_uniqObjects"];
	}
	return re;
}
uniqObjects([x,y,x]);

这也正是 jquery 的思路,由于每个元素都是节点数组,当然可以这样做了:

Js代码 复制代码 收藏代码

  1. unique: function( array ) {   
  2.         var ret = [], done = {};   
  3.   
  4.         try {   
  5.   
  6.             for ( var i = 0, length = array.length; i < length; i++ ) {   
  7.                 var id = jQuery.data( array[ i ] );   
  8.   
  9.                 if ( !done[ id ] ) {   
  10.                     done[ id ] = true;   
  11.                     ret.push( array[ i ] );   
  12.                 }   
  13.             }   
  14.   
  15.         } catch( e ) {   
  16.             ret = array;   
  17.         }   
  18.   
  19.         return ret;   
  20.     },  
unique: function( array ) {
		var ret = [], done = {};

		try {

			for ( var i = 0, length = array.length; i < length; i++ ) {
				var id = jQuery.data( array[ i ] );

				if ( !done[ id ] ) {
					done[ id ] = true;
					ret.push( array[ i ] );
				}
			}

		} catch( e ) {
			ret = array;
		}

		return ret;
	},
 

注意:对基本类型,如 number,string,不要使用这种方式,它们会产生临时对象,并不能达到预期效果!