定义和用法 array_slice() 函数在数组中根据条件取出一段值,并返回。 注释:如果数组有字符串键,所返回的数组将保留键名。(参见例子 4) 语法
1 |
array_slice(<i>array</i>,<i>offset</i>,<i>length</i>,<i>preserve</i>) |
参数 描述 array 必需。规定输入的数组。 offset 必需。数值。规定取出元素的开始位置。 如果是正数,则从前往后开始取,如果是负值,从后向前取 offset 绝对值。 length 可选。数值。规定被返回数组的长度。 如果 length 为正,则返回该数量的元素。 如果 length 为负,则序列将终止在距离数组末端这么远的地方。 如果省略,则序列将从 offset 开始直到 array 的末端。 preserve 可选。可能的值: true – 保留键 false – 默认 – 重置键 例子 1
1 2 3 4 |
<?php $a=array(0=>"Dog",1=>"Cat",2=>"Horse",3=>"Bird"); print_r(array_slice($a,1,2)); ?> |
输出:
1 |
Array ( [0] => Cat [1] => Horse ) |
例子 2 带有负的 offset 参数:
1 2 3 4 |
<?php $a=array(0=>"Dog",1=>"Cat",2=>"Horse",3=>"Bird"); print_r(array_slice($a,-2,1)); ?> |
输出:
1 |
Array ( [0] => Horse ) |
例子 3 preserve 参数设置为 true:
1 2 3 4 |
<?php $a=array(0=>"Dog",1=>"Cat",2=>"Horse",3=>"Bird"); print_r(array_slice($a,1,2,true)); ?> |
输出:
1 |
Array ( [1] => Cat [2] => Horse ) |
例子 4 带有字符串键:
1 2 3 4 |
<?php $a=array("a"=>"Dog","b"=>"Cat","c"=>"Horse","d"=>"Bird"); print_r(array_slice($a,1,2)); ?> |
输出:
1 |
Array ( [b] => Cat [c] => Horse ) |
队列(Queue)在程序设计中扮演着重要的角色,因为它可以模拟队列的数据操作。例 如,排队买票就是一个队列操作,新来的人排在后面,先来的人排在前面,并且买票请求 先被处理。为了模拟队列的操作,Queue在ArrayList的基础上加入了以下限制: · 元素采用先入先出机制(FIFO,First In First Out),即先进入队列的元素必须先离 开队列。最先进入的元素称为队头元素。 · 元素只能被添加到队尾(称为入队),不允许在中间的某个位置插入。也就是说, 不支持ArrayList中的Insert方法。 · 只有队头的元素才能被删除(称为出队),不允许直接对队列中的非队头元素进行 删除,从而保证FIFO机制。也就是说,不支持ArrayList中的Remove方法。 · 不允许直接对队列中非队头元素进行访问。也就是说,不支持ArrayList中的索引访 问,只允许遍历访问。 下面的实例展示了如何创建Queue对象,并向Queue对象中入队数据、出队数据、遍历 数据。 创建TestQueue类,在TestQueue.cs中输入如下代码: using System; using System.Collections.Generic; using System.Text; using System.Collections; namespace Chapter12 { class TestQueue { static void Print(Queue list) { Console.Write("队列内容:"); foreach (string str in list) System.Console.Write(str + " "); } static void Main(string[] args) { Queue list = new Queue(); //Add elements Console.WriteLine("输入字符串添加到队列(#号结束):"); string str; do { str = Console.ReadLine(); if (str == "#") break; else { list.Enqueue(str); } } while (true); TestQueue.Print(list); Console.WriteLine(); //Remove elements Console.WriteLine("出队字符串:"); while (list.Count != 0) […]
View Detailsvolatile 关键字指示一个字段可以由多个同时执行的线程修改。 声明为 volatile 的字段不受编译器优化(假定由单个线程访问)的限制。 这样可以确保该字段在任何时间呈现的都是最新的值。 volatile 修饰符通常用于由多个线程访问但不使用 lock 语句对访问进行序列化的字段。 volatile 关键字可应用于以下类型的字段: 引用类型。 指针类型(在不安全的上下文中)。 请注意,虽然指针本身可以是可变的,但是它指向的对象不能是可变的。 换句话说,您无法声明“指向可变对象的指针”。 类型,如 sbyte、byte、short、ushort、int、uint、char、float 和 bool。 具有以下基类型之一的枚举类型:byte、sbyte、short、ushort、int 或 uint。 已知为引用类型的泛型类型参数。 IntPtr 和 UIntPtr。 可变关键字仅可应用于类或结构字段。 不能将局部变量声明为 volatile。 示例 下面的示例说明如何将公共字段变量声明为 volatile。 C#
1 2 3 4 5 6 7 8 9 |
<span style="color: blue;">class</span> VolatileTest { <span style="color: blue;">public</span> <span style="color: blue;">volatile</span> <span style="color: blue;">int</span> i; <span style="color: blue;">public</span> <span style="color: blue;">void</span> Test(<span style="color: blue;">int</span> _i) { i = _i; } } |
下面的示例演示如何创建辅助线程,并用它与主线程并行执行处理。 有关多线程处理的背景信息,请参见托管线程处理和线程处理(C# 和 Visual Basic)。 C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
<span style="color: blue;">using</span> System; <span style="color: blue;">using</span> System.Threading; <span style="color: blue;">public</span> <span style="color: blue;">class</span> Worker { <span style="color: green;">// This method is called when the thread is started.</span> <span style="color: blue;">public</span> <span style="color: blue;">void</span> DoWork() { <span style="color: blue;">while</span> (!_shouldStop) { Console.WriteLine(<span style="color: #a31515;">"Worker thread: working..."</span>); } Console.WriteLine(<span style="color: #a31515;">"Worker thread: terminating gracefully."</span>); } <span style="color: blue;">public</span> <span style="color: blue;">void</span> RequestStop() { _shouldStop = <span style="color: blue;">true</span>; } <span style="color: green;">// Keyword volatile is used as a hint to the compiler that this data</span> <span style="color: green;">// member is accessed by multiple threads.</span> <span style="color: blue;">private</span> <span style="color: blue;">volatile</span> <span style="color: blue;">bool</span> _shouldStop; } <span style="color: blue;">public</span> <span style="color: blue;">class</span> WorkerThreadExample { <span style="color: blue;">static</span> <span style="color: blue;">void</span> Main() { <span style="color: green;">// Create the worker thread object. This does not start the thread.</span> Worker workerObject = <span style="color: blue;">new</span> Worker(); Thread workerThread = <span style="color: blue;">new</span> Thread(workerObject.DoWork); <span style="color: green;">// Start the worker thread.</span> workerThread.Start(); Console.WriteLine(<span style="color: #a31515;">"Main thread: starting worker thread..."</span>); <span style="color: green;">// Loop until the worker thread activates.</span> <span style="color: blue;">while</span> (!workerThread.IsAlive) ; <span style="color: green;">// Put the main thread to sleep for 1 millisecond to</span> <span style="color: green;">// allow the worker thread to do some work.</span> Thread.Sleep(1); <span style="color: green;">// Request that the worker thread stop itself.</span> workerObject.RequestStop(); <span style="color: green;">// Use the Thread.Join method to block the current thread </span> <span style="color: green;">// until the object's thread terminates.</span> workerThread.Join(); Console.WriteLine(<span style="color: #a31515;">"Main thread: worker thread has terminated."</span>); } <span style="color: green;">// Sample output:</span> <span style="color: green;">// Main thread: starting worker thread...</span> <span style="color: green;">// Worker thread: working...</span> <span style="color: green;">// Worker thread: working...</span> <span style="color: green;">// Worker thread: working...</span> <span style="color: green;">// Worker thread: working...</span> <span style="color: green;">// Worker thread: working...</span> <span style="color: green;">// Worker thread: working...</span> <span style="color: green;">// Worker thread: terminating gracefully.</span> <span style="color: green;">// Main thread: worker thread has terminated.</span> } from:http://msdn.microsoft.com/zh-cn/library/x13ttww7.aspx |
1. 源码下载: 下载地址:http://files.cnblogs.com/tianzhiliang/ManualResetEventDemo.rar Demo: 2. ManualResetEvent详解 ManualResetEvent 允许线程通过发信号互相通信。通常,此通信涉及一个线程在其他线程进行之前必须完成的任务。当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时,它调用 Reset 以将 ManualResetEvent 置于非终止状态,此线程可被视为控制 ManualResetEvent。调用 ManualResetEvent 上的 WaitOne 的线程将阻止,并等待信号。当控制线程完成活动时,它调用 Set 以发出等待线程可以继续进行的信号。并释放所有等待线程。一旦它被终止,ManualResetEvent 将保持终止状态(即对 WaitOne 的调用的线程将立即返回,并不阻塞),直到它被手动重置。可以通过将布尔值传递给构造函数来控制 ManualResetEvent 的初始状态,如果初始状态处于终止状态,为 true;否则为 false。 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ManualResetEventDemo { class MREDemo { private ManualResetEvent _mre; public MREDemo() { this._mre = new ManualResetEvent(true); } public void CreateThreads() { Thread t1 = new Thread(new ThreadStart(Run)); t1.Start(); Thread t2 = new Thread(new ThreadStart(Run)); t2.Start(); } public void Set() { this._mre.Set(); } public void Reset() { this._mre.Reset(); } private void Run() { string strThreadID = string.Empty; try { while (true) { // 阻塞当前线程 this._mre.WaitOne(); strThreadID = Thread.CurrentThread.ManagedThreadId.ToString(); Console.WriteLine("Thread(" + strThreadID + ") is running…"); Thread.Sleep(5000); } […]
View Details相关概念: 线程池可以看做容纳线程的容器; 一个应用程序最多只能有一个线程池; ThreadPool静态类通过QueueUserWorkItem()方法将工作函数排入线程池; 每排入一个工作函数,就相当于请求创建一个线程; 线程池的作用: 线程池是为突然大量爆发的线程设计的,通过有限的几个固定线程为大量的操作服务,减少了创建和销毁线程所需的时间,从而提高效率。 如果一个线程的时间非常长,就没必要用线程池了(不是不能作长时间操作,而是不宜。),况且我们还不能控制线程池中线程的开始、挂起、和中止。 什么时候使用ThreadPool? ThreadPool 示例一 : ThreadPool_1.cs using System; using System.Text; using System.Threading; namespace 多线程 { public class Example { public static void Main() { // Queue the task. ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc)); Console.WriteLine("Main thread does some work, then sleeps."); Thread.Sleep(1000); Console.WriteLine("Main thread exits."); } static void ThreadProc(Object stateInfo) { // No state object was passed to QueueUserWorkItem, // so stateInfo is null. Console.WriteLine("Hello from the thread pool."); } } } ThreadPool 示例二 : ThreadPool_2.cs using System; using System.Collections.Generic; using System.Text; using System.Threading; namespace CS_Test { class ThreadPool_Demo { // 用于保存每个线程的计算结果 static int[] result = new int[10]; //注意:由于WaitCallback委托的声明带有参数, // 所以将被调用的Fun方法必须带有参数,即:Fun(object obj)。 static void Fun(object obj) { int n = (int)obj; //计算阶乘 int fac = 1; for (int i = 1; i <= n; i++) { fac *= i; } //保存结果 result[n] = fac; } static void Main(string[] args) { //向线程池中排入9个工作线程 for (int i = 1; i <= 9 ; i++) { //QueueUserWorkItem()方法:将工作任务排入线程池。 ThreadPool.QueueUserWorkItem(new WaitCallback(Fun),i); // Fun 表示要执行的方法(与WaitCallback委托的声明必须一致)。 // i 为传递给Fun方法的参数(obj将接受)。 } //输出计算结果 for (int i = 1; i <= 9; i++) { Console.WriteLine("线程{0}: {0}! = {1}",i,result[i]); } } } } ThreadPool的作用: 参考来源: C#多线程学习(四) 多线程的自动管理(线程池) [叩响C#之门]写给初学者:多线程系列( 十一)——线程池(ThreadPool) from:http://www.cnblogs.com/xugang/archive/2010/04/20/1716042.html
View DetailsMariaDB也是由MySQL创始人发明的。并且由于MySQL被甲骨文收购,正在成为开源数据库的主流。 据悉,维基传媒基金会负责网站架构的高层Asher Feldman透露,他最近将维基百科中的英文百科全书,转移到了MariaDB 5.5.28数据库。他透露,明年一季度末期,有望把整个百科全书切换到新的开源数据库。 在谈到更换数据库平台的原因时,这位高层表示,主要目的并不是新数据库性能更好,维基传媒基金会以及整个开源社群,都希望能够推动开源数据库MariaDB的普及。 MariaDB官网 我们可以从MariaDB官网上看到,MariaDB数据库的定位就是MySQL的替代者。 有国外媒体指出,此次维基百科选用MariaDB,势必让全球诸多采用Linux, Apache, MySQL, PHP/Python/Perl (LAMP)套件技术的开发者更多关注MariaDB。 from:http://database.51cto.com/art/201212/373189.htm
View Details在多个平台上测试多种浏览器不但是很困难的 – 它几乎不可能的,因为没有那些好的测试工具。今天,我们就为大家提供很多涉及到跨浏览器测试的选择,并且告诉你那些“顶级的浏览器测试工具”,你应该使用哪一个。 这前10名的免费跨浏览器测试工具没有特定的顺序,因为他们对于任何特定的设备都同样有效。如果你手动去测试,可能既困难又耗费时间。因为你只能不断的安装更多的浏览器在你的设备上。 不要忘了在下面评论一下,留点反馈信息来改善我的博客质量额。如果你喜欢这篇文章,可能有兴趣看看其他相关的一些文章: 1. Browsera Browsera 可以测试和报告在您的网站上的跨浏览器布局的差异和脚本错误。 Browsera不同于其他跨浏览器测试服务。其他服务,如Litmus,Browsershots,BrowserLab,以及 SuperPreview,它们仅仅截取每一个特定的页面,你必须具体再分析才行。 官方网站 2. BrowserStack BrowserStack提供实时的,基于Web的浏览器测试的能力。可以即时访问每个桌面和移动浏览器(目前超过300个),具有在内部服务器进行本地测试的能力,并且提供一个安全的设置。 官方网站 3. Lunascape Lunascape是一款免费的三重引擎的浏览器。这意味着,你可以用三叉戟(IE),蛤蚧(火狐)和Webkit(Chrome和Safari)运行和测试一个新的网站,并且可以排在一起比较渲染引擎的效果。 官方网站 4. CrossBrowserTesting CrossBrowserTesting允许用户与超过100分辨率/浏览器/操作系统组合,测试他们的网站。它还为移动网络浏览器提供重要的支持,因为现在的互联网流量正从主要的桌面电脑用户向移动用户进行转移。 官方网站 5. Browserling Browserling和Testling作为我们部署测试流程的一部分,是基于我们公布的JavaScript库的PubNub JavaScript的用户群。这可以对快速测试所有的JavaScript环境提供一流的服务。 官方网站 6. Browsershots Browsershots可以为你设计的网页在不同的操作系统和浏览器中进行屏幕截图。这是一个免费开源的在线Web应用程序,开发人员提供了一个简单方法来测试在他们的网站在一个地方的浏览器兼容性。 官方网站 7. Litmus Litmus 提供跨浏览器网页测试,而且可以发送到你电子邮件进行预览。只要填写一个网址,它就会告诉你怎样适应当下流行的Web浏览器。 官方网站 8. Spoon Spoon 是一个很好的资源,它可以让你实时使用最流行的浏览器测试你的网站,包括Opera,火狐,Chrome和Safari等。 不过IE浏览器是不允许的,因为微软不提供许可。 官方网站 9. Sauce Labs Sauce Labs 提供了一个相当独特的跨浏览器测试体验。它并不是简单地把你的网站在不同的浏览器进行截图,而是室可以让你记录你网站的实时测试效果。 官方网站 10. Ghostlab Ghostlab提供同步测试滚动,点击,重新加载等,并形成信息输入到所有的连接设备,这意味着你可以测试整个用户体验,而不仅仅是一个简单的页面。 官方网站 总结:已经工作的时候很少用到专业的浏览器测试工具。大都是用个ieTest加上火狐和chrome就搞定一切了,多了也就是用个在线网页测试工具。一些细微的兼容性测试也是自己慢慢修改,费时又耗力。想要确保代码在各种主流浏览器的各个版本中都能正常工作,建议还是用一下上面提供的这些浏览器兼容性测试工具吧,应该能够事半功倍! 注:原文参考自:Top 10 Great Free Cross Browser Testing Tools 。本文由欲思原创编译,部分翻译删改或有误请谅解。 稿源:欲思博客 » 盘点前10名的免费跨浏览器测试工具 from:http://www.oschina.net/news/53246/free-cross-browser-testing-tools
View Details//封装类 [csharp] view plaincopyprint? using System; using System.Collections.Generic; using System.Linq; using System.Web; using Lucene.Net.Analysis; using Lucene.Net.Index; using Lucene.Net.Documents; using System.Reflection; using Lucene.Net.QueryParsers; using Lucene.Net.Search; namespace SearchTest { /// <summary> /// 盘古分词在lucene.net中的使用帮助类 /// 调用PanGuLuceneHelper.instance /// </summary> public class PanGuLuceneHelper { private PanGuLuceneHelper() { } #region 单一实例 private static PanGuLuceneHelper _instance = null; /// <summary> /// 单一实例 /// </summary> public static PanGuLuceneHelper instance { get { if (_instance == null) _instance = new PanGuLuceneHelper(); return _instance; } } #endregion #region 分词测试 /// <summary> /// 分词测试 /// </summary> /// <param name="keyword"></param> /// <returns></returns> public string Token(string keyword) { string ret = ""; System.IO.StringReader reader = new System.IO.StringReader(keyword); Lucene.Net.Analysis.TokenStream ts = analyzer.TokenStream(keyword, reader); bool hasNext = ts.IncrementToken(); Lucene.Net.Analysis.Tokenattributes.ITermAttribute ita; while (hasNext) { ita = ts.GetAttribute<Lucene.Net.Analysis.Tokenattributes.ITermAttribute>(); ret += ita.Term + "|"; hasNext = ts.IncrementToken(); } ts.CloneAttributes(); reader.Close(); analyzer.Close(); return ret; } #endregion #region 创建索引 /// <summary> /// 创建索引 /// </summary> /// <param name="datalist"></param> /// <returns></returns> public bool CreateIndex(List<MySearchUnit> datalist) { IndexWriter writer = null; try { writer = new IndexWriter(directory_luce, analyzer, false, IndexWriter.MaxFieldLength.LIMITED);//false表示追加(true表示删除之前的重新写入) } catch { writer = new IndexWriter(directory_luce, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);//false表示追加(true表示删除之前的重新写入) } foreach (MySearchUnit data in datalist) { CreateIndex(writer, data); } writer.Optimize(); […]
View Details如果您想详细了解eval和JSON请参考以下链接: eval :https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Global_Functions/Eval JSON:http://www.json.org/ eval函数的工作原理 eval函数会评估一个给定的含有JavaScript代码的字符串,并且试图去执行包含在字符串里的表达式或者一系列的合法的JavaScript语句。eval函数将把最后一个表达式或者语句所包含的值或引用作为返回值。 举例说明 eval评估JavaScript表达式
1 2 3 |
<span class="sh_keyword" style="font-weight: bold; color: blue;">var</span> bar <span class="sh_symbol" style="color: #8b0000;">=</span> <span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">'bar'</span></span><span class="sh_symbol" style="color: #8b0000;">;</span><span class="sh_keyword" style="font-weight: bold; color: blue;"> var</span> foobar <span class="sh_symbol" style="color: #8b0000;">=</span> <span class="sh_predef_func" style="font-weight: bold; color: #00008b;">eval</span><span class="sh_symbol" style="color: #8b0000;">(</span><span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">'"foo" + bar'</span></span><span class="sh_symbol" style="color: #8b0000;">);</span><span class="sh_predef_func" style="font-weight: bold; color: #00008b;"> alert</span><span class="sh_symbol" style="color: #8b0000;">(</span>foobar<span class="sh_symbol" style="color: #8b0000;">);</span> |
eval评估JavaScript语句
1 2 3 4 5 6 7 8 9 10 |
<span class="sh_keyword" style="font-weight: bold; color: blue;">var</span> bar <span class="sh_symbol" style="color: #8b0000;">=</span> <span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">'bar'</span></span><span class="sh_symbol" style="color: #8b0000;">;</span><span class="sh_comment" style="font-style: italic; color: #a52a2a;"> // if variable bar equals 'bar', foobar is the result of </span><span class="sh_comment" style="font-style: italic; color: #a52a2a;">// last executing statement: bar="foo-bar";</span><span class="sh_keyword" style="font-weight: bold; color: blue;"> var</span> foobar <span class="sh_symbol" style="color: #8b0000;">=</span> <span class="sh_predef_func" style="font-weight: bold; color: #00008b;">eval</span><span class="sh_symbol" style="color: #8b0000;">(</span><span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">'if(bar == "bar") {bar="foo-bar";} else {bar = "bar-foo";}'</span></span><span class="sh_symbol" style="color: #8b0000;">);</span><span class="sh_predef_func" style="font-weight: bold; color: #00008b;"> alert</span><span class="sh_symbol" style="color: #8b0000;">(</span>foobar<span class="sh_symbol" style="color: #8b0000;">);</span><span class="sh_comment" style="font-style: italic; color: #a52a2a;">// change the value</span>bar <span class="sh_symbol" style="color: #8b0000;">=</span> <span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">'foo'</span></span><span class="sh_symbol" style="color: #8b0000;">;</span><span class="sh_comment" style="font-style: italic; color: #a52a2a;"> // now our the last executed statement is: bar = "bar-foo";</span><span class="sh_comment" style="font-style: italic; color: #a52a2a;"> // therefore the value of variable foobar has been changed</span><span class="sh_comment" style="font-style: italic; color: #a52a2a;"> // into 'bar-foo'</span> foobar <span class="sh_symbol" style="color: #8b0000;">=</span> <span class="sh_predef_func" style="font-weight: bold; color: #00008b;">eval</span><span class="sh_symbol" style="color: #8b0000;">(</span><span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">'if(bar == "bar") {bar="foo-bar";} else {bar = "bar-foo";}'</span></span><span class="sh_symbol" style="color: #8b0000;">);</span><span class="sh_predef_func" style="font-weight: bold; color: #00008b;"> alert</span><span class="sh_symbol" style="color: #8b0000;">(</span>foobar<span class="sh_symbol" style="color: #8b0000;">);</span> |
JSON的格式 JSON的格式是由大括号和由冒号(:)构成的名值对所组成的。注意JSON格式与对象字面量 (object literals) 的区别:JSON的名字部分严格用引号+名字来表示。 举例说明 对象的字面量
1 2 3 4 5 6 7 8 |
<span class="sh_keyword" style="font-weight: bold; color: blue;">var</span> objectLiteral <span class="sh_symbol" style="color: #8b0000;">=</span> <span class="sh_cbracket" style="color: red;">{</span> <span class="sh_predef_var" style="color: #00008b;">name</span><span class="sh_symbol" style="color: #8b0000;">:</span> <span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">"Objector.L"</span></span><span class="sh_symbol" style="color: #8b0000;">,</span> age<span class="sh_symbol" style="color: #8b0000;">:</span> <span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">"24"</span></span><span class="sh_symbol" style="color: #8b0000;">,</span> special<span class="sh_symbol" style="color: #8b0000;">:</span> <span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">"JavaScript"</span></span><span class="sh_symbol" style="color: #8b0000;">,</span> sayName<span class="sh_symbol" style="color: #8b0000;">:</span> <span class="sh_keyword" style="font-weight: bold; color: blue;">function</span><span class="sh_symbol" style="color: #8b0000;">()</span> <span class="sh_cbracket" style="color: red;">{</span> <span class="sh_keyword" style="font-weight: bold; color: blue;">return</span> <span class="sh_keyword" style="font-weight: bold; color: blue;">this</span><span class="sh_symbol" style="color: #8b0000;">.</span><span class="sh_predef_var" style="color: #00008b;">name</span><span class="sh_symbol" style="color: #8b0000;">;</span> <span class="sh_cbracket" style="color: red;">}</span><span class="sh_cbracket" style="color: red;"> }</span><span class="sh_symbol" style="color: #8b0000;">;</span> |
JSON对象
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<span class="sh_keyword" style="font-weight: bold; color: blue;">var</span> jsonFormat <span class="sh_symbol" style="color: #8b0000;">=</span> <span class="sh_cbracket" style="color: red;">{ </span> <span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">"summary"</span></span><span class="sh_symbol" style="color: #8b0000;">:</span> <span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">"Blogs"</span></span><span class="sh_symbol" style="color: #8b0000;">, </span> <span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">"blogrolls"</span></span><span class="sh_symbol" style="color: #8b0000;">:</span> <span class="sh_symbol" style="color: #8b0000;">[</span> <span class="sh_cbracket" style="color: red;">{ </span> <span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">"title"</span></span><span class="sh_symbol" style="color: #8b0000;">:</span> <span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">"Explore JavaScript"</span></span><span class="sh_symbol" style="color: #8b0000;">,</span> <span class="sh_string" style="color: red;"><span style="font-family: 新宋体;"> "link"</span></span><span class="sh_symbol" style="color: #8b0000;">:</span> <span style="font-family: 新宋体;"><span class="sh_string" style="color: red;">"http://example.com/"</span> </span> <span class="sh_cbracket" style="color: red;">}</span><span class="sh_symbol" style="color: #8b0000;">, </span> <span class="sh_cbracket" style="color: red;">{</span> <span class="sh_string" style="color: red;"><span style="font-family: 新宋体;"> "title"</span></span><span class="sh_symbol" style="color: #8b0000;">:</span> <span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">"Explore JavaScript"</span></span><span class="sh_symbol" style="color: #8b0000;">,</span> <span class="sh_string" style="color: red;"><span style="font-family: 新宋体;"> "link"</span></span><span class="sh_symbol" style="color: #8b0000;">:</span> <span style="font-family: 新宋体;"><span class="sh_string" style="color: red;">"http://example.com/"</span> </span> <span class="sh_cbracket" style="color: red;">}</span> <span class="sh_symbol" style="color: #8b0000;">]</span><span class="sh_cbracket" style="color: red;"> }</span><span class="sh_symbol" style="color: #8b0000;">;</span> |
eval和JSON 由于Ajax的兴起,JSON这种轻量级的数据格式作为客户端与服务器之间的传输格式逐渐地流行起来,进而出现的问题是如何将服务器端构建好的JSON数据转化为可用的JavaScript对象。利用eval函数无疑是一种简单而直接的方法。在转化的时候需要将JSON字符串的外面包装一层圆括号:
1 |
<span class="sh_keyword" style="font-weight: bold; color: blue;">var</span> jsonObject <span class="sh_symbol" style="color: #8b0000;">=</span> <span class="sh_predef_func" style="font-weight: bold; color: #00008b;">eval</span><span class="sh_symbol" style="color: #8b0000;">(</span><span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">"("</span></span> <span class="sh_symbol" style="color: #8b0000;">+</span> jsonFormat <span class="sh_symbol" style="color: #8b0000;">+</span> <span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">")"</span></span><span class="sh_symbol" style="color: #8b0000;">);</span> |
为什么要加括号? 加上圆括号的目的是迫使eval函数在评估JavaScript代码的时候强制将括号内的表达式(expression)转化为对象,而不是作为语句(statement)来执行。举一个例子,例如对象字面量{},如若不加外层的括号,那么eval会将大括号识别为JavaScript代码块的开始和结束标记,那么{}将会被认为是执行了一句空语句。所以下面两个执行结果是不同的:
1 2 |
<span class="sh_predef_func" style="font-weight: bold; color: #00008b;">alert</span><span class="sh_symbol" style="color: #8b0000;">(</span><span class="sh_predef_func" style="font-weight: bold; color: #00008b;">eval</span><span class="sh_symbol" style="color: #8b0000;">(</span><span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">"{}"</span></span><span class="sh_symbol" style="color: #8b0000;">);</span> <span class="sh_comment" style="font-style: italic; color: #a52a2a;">// return undefined</span><span class="sh_predef_func" style="font-weight: bold; color: #00008b;"> alert</span><span class="sh_symbol" style="color: #8b0000;">(</span><span class="sh_predef_func" style="font-weight: bold; color: #00008b;">eval</span><span class="sh_symbol" style="color: #8b0000;">(</span><span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">"({})"</span></span><span class="sh_symbol" style="color: #8b0000;">);</span><span class="sh_comment" style="font-style: italic; color: #a52a2a;">// return object[Object]</span> |
JSON格式的名字部分为什么要加引号? 因为eval函数会将{foo:”bar”}解释成合法的JavaScript语句,而非表达式。但是人们往往想要的是让eval将这段代码解释成一个对象。所以JSON格式会强制你去在名字的外侧加上引号再结合圆括号,这样eval就不会错误的将JSON解释成代码块。 举例说明 eval错误解析语义
1 |
<span class="sh_predef_func" style="font-weight: bold; color: #00008b;">alert</span><span class="sh_symbol" style="color: #8b0000;">(</span><span class="sh_predef_func" style="font-weight: bold; color: #00008b;">eval</span><span class="sh_symbol" style="color: #8b0000;">(</span><span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">'{foo:"bar"}'</span></span><span class="sh_symbol" style="color: #8b0000;">));</span> <span class="sh_comment" style="font-style: italic; color: #a52a2a;">// return "bar", incorrect</span> |
eval正确解析JSON
1 |
<span class="sh_predef_func" style="font-weight: bold; color: #00008b;">alert</span><span class="sh_symbol" style="color: #8b0000;">(</span><span class="sh_predef_func" style="font-weight: bold; color: #00008b;">eval</span><span class="sh_symbol" style="color: #8b0000;">(</span><span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">'({"foo": "bar"})'</span></span><span class="sh_symbol" style="color: #8b0000;">));</span> <span class="sh_comment" style="font-style: italic; color: #a52a2a;">// return JSON object, correct</span> |
结论 理解eval的工作原理和json的严格的限定格式,合理结合eval和json应用于JavaScript的数据传递和对象转换。 following this format:
1 |
<span class="sh_predef_func" style="font-weight: bold; color: #00008b;">eval</span><span class="sh_symbol" style="color: #8b0000;">(</span><span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">'{'</span></span> <span class="sh_symbol" style="color: #8b0000;">+</span> jsonString <span class="sh_symbol" style="color: #8b0000;">+</span> <span class="sh_string" style="color: red;"><span style="font-family: 新宋体;">')'</span></span><span class="sh_symbol" style="color: #8b0000;">);</span> |
from:http://www.jb51.net/article/21688.htm
View Details目录 一 Lucene.Net概述 二 分词 三 索引 四 搜索 五 实践中的问题 一 Lucene.Net概述 Lucene.Net是一个C#开发的开源全文索引库,其源码包括“核心”与“外围”两部分。外围部分实现辅助功能,而核心部分包括: Lucene.Net.Index 提供索引管理,词组排序。 Lucene.Net.Search 提供查询相关功能。 Lucene.Net.Store 支持数据存储管理,主要包括I/O操作。 Lucene.Net.Util 公共类。 Lucene.Net.Documents 负责描述索引存储时的文件结构管理。 Lucene.Net.QueryParsers 提供查询语法。 Lucene.Net.Analysis 负责分析文本。 全文检索流程如下: 一个简单的全文检索实例: 创建索引: 关键代码形如:
1 2 3 4 5 6 7 8 9 10 11 |
static void createIndex(string title, string content) { LN.Analysis.Analyzer analyzer = new LN.Analysis.Standard.StandardAnalyzer(); LN.Index.IndexWriter iw = new LN.Index.IndexWriter("Index", analyzer, false); LN.Documents.Document document = new LN.Documents.Document(); document.Add(new LN.Documents.Field("title", title, LN.Documents.Field.Store.YES, LN.Documents.Field.Index.TOKENIZED)); document.Add(new LN.Documents.Field("content", content, LN.Documents.Field.Store.YES, LN.Documents.Field.Index.TOKENIZED)); iw.AddDocument(document); iw.Optimize(); iw.Close(); } |
查询: 关键代码形如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
static List<Item> search(string keyWord) { List<Item> results = new List<Item>(); LN.Analysis.Analyzer analyzer = new LN.Analysis.Standard.StandardAnalyzer(); LN.Search.IndexSearcher searcher = new LN.Search.IndexSearcher("Index"); LN.QueryParsers.MultiFieldQueryParser parser = new LN.QueryParsers.MultiFieldQueryParser(new string[] { "title", "content" }, analyzer); LN.Search.Query query = parser.Parse(keyWord); LN.Search.Hits hits = searcher.Search(query); for (int i = 0; i < hits.Length(); i++) { LN.Documents.Document doc = hits.Doc(i); results.Add(new Item() { Title = doc.Get("title"), Content = doc.Get("content") }); } searcher.Close(); return results; } |
二 分词 (一)内置分词器 分词(切词)是实现全文检索的基础,之所以我们能够让机器理解我们的自然语言,是因为有了分词的帮助。分词工作由Analyzer类完成,它负责把文本切成Token序列,Token就是索引中的单词。Lucene.Net在两个地方用到分词:创建文档索引和分析搜索关键字。其过程示意如下: 由此可知,在创建索引和搜索时,必须使用同样的分词器,保证其切出相同的Token才能检索到结果。(Lucene.Net把查询关键字中的单词叫做“Term”,Term和Token的文本是一样的,只是某些属性不一样。) Lucene.Net实现了一些分词器,其对英文支持较好,但是对中文支持欠佳。 针对内置分词器测试结果如下: 关键代码形如:
1 2 3 4 5 6 7 8 9 10 11 12 |
private static List<string> cutWords(string words, Analyzer analyzer) { List<string> results = new List<string>(); TokenStream ts = analyzer.ReusableTokenStream("", new StringReader(words)); Token token; while ((token = ts.Next()) != null) { results.Add(token.TermText()); } ts.Close(); return results; } |
可见,除了StandardAnalyzer外,其它分词器对中文基本无法处理,需要用户自行解决。 (二)分词过程 分词实际是由以下类型完成: 查看WhitespaceAnalyzer的部分源码如下:
1 2 3 4 5 6 7 8 |
public sealed class WhitespaceAnalyzer:Analyzer { public override TokenStream TokenStream(System.String fieldName, System.IO.TextReader reader) { return new WhitespaceTokenizer(reader); } ... } |
由此可见,WhitespaceAnalyzer的工作都是交给WhitespaceTokenizer来完成的,并且没有使用筛选器,这也与之前测试的结果相符。我们可以利用TokenStream的派生类型来实现自定义分词器。 例如修改上述代码来得到一个新的分词器,功能类似WhitespaceAnalyzer,不同的是将大写字母变为小写,其代码形如:
1 2 3 4 5 6 7 8 9 |
public sealed class NewWhitespaceAnalyzer:Analyzer { public override TokenStream TokenStream(System.String fieldName, System.IO.TextReader reader) { TokenStream ts = new WhitespaceTokenizer(reader); return new LowerCaseFilter(ts); } ... } |
(三)中文分词 显然,用户可以自定义分词器,来实现中文分词。但是,大多数用户不熟悉中文分词算法,同时也没有时间和精力来实现自定义分词,毕竟分词并不是我们系统的核心功能。因此,笔者引用了另一个中文分词组件——盘古分词。测试结果如下: 盘古分词使用步骤如下: Setp 1:添加相关程序集引用 这里需要添加2个程序集,PanGu.dll(盘古分词的核心组件)和PanGu.Lucene.Analyzer.dll(盘古分词的Lucene组件)。 Step 2:添加中文分词库 Step 3:添加并设置配置文件 Step 4:在Lucene.Net使用盘古分词 PanGu.Lucene.Analyzer.dll中定义了Analyzer的派生类型Lucene.Net.Analysis.PanGu.PanGuAnalyzer,与Tokenizer的派生类Lucene.Net.Analysis.PanGu.PanGuTokenizer,语法与Lucene.Net内置分词器相同。 Step 5:维护分词库 使用DictManage.exe管理和维护词库: 三 索引 (一)索引的存储结构 为了方便索引大量文档,Lucene.Net中的一个索引包括多个子索引,叫做Segment(段)。每个Segment包括多个可搜索的文档,叫做Document;每个Document包括多个Field;每个Field又包括多个Term。综上所述,Lucene.Net的索引文件的逻辑结构如下: 索引文件的物理表示如下: Lucene.Net把一个文档写入索引时,首先生成这个文档的到排索引,然后再把文档的倒排索引合并到段的倒排索引中。 (二)常用类型 Directory Lucene.Net的Directory类型实现索引的存储。常用类型继承树如下: IndexWriter 负责将索引写入Directory。Lucene通过设置缓存来提供写索引的速度,IndexWriter有几个参数来调整缓存的大小,控制Segment的数量,以及写索引的频率: 合并因子(mergeFactor) 这个参数决定一个索引块中可以存放多少文档(Document)以及把磁盘上的索引段(Segment)合并成一个大索引段的频率。该参数默认值为10。在默认情况下,缓存中Document数达到10时,所有的文档将写入一个新的Segment。并且,如果Directory的Segment的个数达到10,这10个索引块会被合并成一个新的Segment。对于大量文档来说,这个值大一些会更好。可以通过“SetMergeFactor(int mergeFactor)”方法来设置、 最小合并文档数(minMergeDocs)、最大缓存文档数(maxBufferedDocs) 默认值为10,它决定缓存中Document数量达到多少才能将他们写入磁盘。该值越大越消耗内存,I/O操作越少。(本处,笔者也有些糊涂,笔者感觉两者类似,不知道具体区别,若理解有误还请读者赐教。) 最大合并文档数(maxMergeDocs) 默认值为Integer.MAX_VALUE,它决定一个索引段(Segment)中的最大文档(Document)数。该值越大越高效,因为默认值以及很大了所以不用改变。 最大域长度(maxFieldLength) 默认值10000,表示截取该域中的前10000个Term,前10000个以外的Term将不被索引和检索。该值可在索引中随时更改,并即时生效(仅对之后的操作生效,一般该值设置为Integer.MAX_VALUE)。 IndexWriter的常用方法包括: Flush/Commit Flush方法与Commit方法相同,都是把缓存中的数据提交,可以清除缓存。 Close 无论是否发生异常都必须调用Close方法,该方法将对文件进行解锁,并完成Flush方法的功能。 Optimize Optimize方法用于优化索引,执行相当耗时。 Document 包含了可索引文档的信息。每个Document都有一个编号,但该编号并非永远不变。 Field 类似实体的某个属性,就像数据库中的一个列,其成员如下: (可以看到,Index的某些字段我给出的相同的注释,这是因为向下兼容的目的而具有相同的作用。注:高亮显示将用的TermVector。) […]
View Details