首页 > PHP,Javascript > js数组元素排队思路完美解决将浏览记录到cookie的问题

js数组元素排队思路完美解决将浏览记录到cookie的问题

今天写js+cookie记录用户浏览文章的历史记录,考虑到使用js数组对文章ID进行排队,思路如下:如果数组中已经存在文章ID应该将其移动到队列尾部,不存在则直接添加到尾部。然后写完了js代码,感觉不是很完美,于是单独封装了一个js函数,只需要传入js数组和新增的元素,即可返回重新排好队的数组,js代码如下:

/**
* 对数组重新进行排队,传入new_value在max个元素限制下
* 如果new_value存在于数组中则移动到最后,如果不存在则在最后增加
* @param    Array    arr        js数组,参数类型[String,String,String……]
* @param    String   new_value  新增元素,参数类型:String
* @param    int      max        元素容量,参数类型:int
* @return   Array               过滤和重新排队后的数组,[String,String,String……]
* @author   shuiguang
*/
function arr_queue(arr, new_value, max){
    var brr = new Array();                  //除去重复和空的元素,最终元素个数小于等于max
    var count = 0;                          //使用新数组去掉旧数组的空值
    var flag = false;                       //假设没有相同处
    var same = 0;                           //假设相同值位于第一位
    //第一个循环:去除空值和检查是否有相同值,如果有则记下索引值
    for(var i=0; i<arr.length; i++){
        brr[count] = arr[i];
        if(brr[count] == new_value){
            flag = true;
            same = count;
        }
        count++;
        if(count >= max)    break;          //最大不能超过max
    }
    //第二个循环:要么增加,要么移动
    //思路:首先用flag判断是否有相同,如果有相同只需将其移到最前0也可以;如果没有只需增加时判断长度2种
    //增加的条件是:flag==false;brr.length<max
    //其余的都是移动即flag==false时的满长整体后移,部分后移和flag==true时的满长整体后移,部分后移。
    //但是只需要保证(移动)brr[brr.length-1]=value即可
    if(flag == false && brr.length < max){  //增加
        brr[brr.length] = new_value;
    }else{
        for(var i=0; i<brr.length-1; i++){
            if(i >= same){                  //不管找没找到都给我前移一位,其实它是分了2种情况合并了的
                brr[i] = brr[i+1];
            }
        }
        brr[brr.length-1] = new_value;      //目的就是移动,不会有增加的,所以只需要设置一个值
    }
    return brr;
}


由于cookie的存储空间有限,所以还添加了一个max参数,建议不要设置太大。之前在谷歌,火狐,IE8等下测试非常,唯独在IE6下测试非常怪异,后来在别人的博客里了解到IE6的cookie丢失的问题,将max调小并且清空cookie之后竟然正常了,所以上面的这个函数还是可以用的。

IE6下的bug参见这篇文章:http://www.cnblogs.com/kkun/archive/2011/07/06/2099366.html


得到排好序的js数组之后再组装成cookie字符串写入cookie,到此算是解决。后来,又增加新的功能,要求cookie里面不仅仅保存文章ID,还有其他字段,点击量什么的,不能使用简单的一维数组了,于是稍微带动了一下上面的函数,将单个元素改为数组:[主键,其他字段 对象],优化后的js代码如下:

/**
* 对数组重新进行排队,传入new_value在max个元素限制下,
* 如果new_value存在于数组中则移动到最后,如果不存在则在最后增加
* @param    Array    arr        js数组,参数类型[[String, Object],[String, Object],[String, Object]……]
* @param    String   new_value  新增元素,参数类型:[String, Object]
* @param    int      max        元素容量,参数类型:int
* @return   Array               过滤和重新排队后的数组,[[String, Object],[String, Object],[String, Object]……]
* @author   shuiguang
*/
function arr_queue(arr, new_value, max){
    var brr = new Array();                  //除去重复和空的元素,最终元素个数小于等于max
    var count = 0;                          //使用新数组去掉旧数组的空值
    var flag = false;                       //假设没有相同处
    var same = 0;                           //假设相同值位于第一位
    //第一个循环:去除空值和检查是否有相同值,如果有则记下索引值
    for(var i=0; i<arr.length; i++){
        brr[count] = arr[i];
        if(brr[count][0] == new_value[0]){
            flag = true;
            same = count;
        }
        count++;
        if(count >= max)    break;          //最大不能超过max
    }
    //第二个循环:要么增加,要么移动
    //思路:首先用flag判断是否有相同,如果有相同只需将其移到最前0也可以;如果没有只需增加时判断长度2种
    //增加的条件是:flag==false;brr.length<max
    //其余的都是移动即flag==false时的满长整体后移,部分后移和flag==true时的满长整体后移,部分后移。
    //但是只需要保证(移动)brr[brr.length-1]=value即可
    if(flag == false && brr.length < max){  //增加
        brr[brr.length] = new_value;
    }else{
        for(var i=0; i<brr.length-1; i++){
            if(i >= same){                  //不管找没找到都给我前移一位,其实它是分了2种情况合并了的
                brr[i] = brr[i+1];
            }
        }
        brr[brr.length-1] = new_value;      //目的就是移动,不会有增加的,所以只需要设置一个值
    }
    return brr;
}
console.log(arr_queue([[34,{title:"测试34",onclick:"100"}],[12,{title:"测试12",onclick:"200"}], [56,{title:"测试56",onclick:"300"}]], [78,{title:"测试56",onclick:"300"}], 5));
console.log(arr_queue([[34,{title:"测试34",onclick:"100"}],[12,{title:"测试12",onclick:"200"}], [56,{title:"测试56",onclick:"300"}]], [78,{title:"测试56",onclick:"300"}], 3));
console.log(arr_queue([[34,{title:"测试34",onclick:"100"}],[12,{title:"测试12",onclick:"200"}], [56,{title:"测试56",onclick:"300"}]], [12,{title:"测试56",onclick:"300"}], 3));


对上面改动的函数进行测试之后,可以正常运行,不过还是需要注意IE6下的cookie长度问题,到此工作问题完美解决。


========================================================================================================


根据上面的思路稍加改动便可写出响应的php版本,php代码如下:


<?php
/**
* 对数组重新进行排队,传入$new_value在$max个元素限制下
* 如果$new_value存在于数组中则移动到最后,如果不存在则在最后增加
* @param    array    arr		php数组,参数类型array(array(string, mix),array(string, mix)……)
* @param    string   new_value	新增元素,参数类型:array(string, mix)
* @param    int		 max		元素容量,参数类型:boolean(false为传入数组的长度), int(手动指定长度)
* @return   Array  	 			过滤和重新排队后的数组,array(array(string, mix),array(string, mix)……)
* @author   shuiguang
*/
function arr_queue($arr, $new_value, $max = false)
{
	if(!is_array($arr) || !is_array($new_value) || !isset($new_value[1]))
	{
		return false;
	}
	$max = ($max == false) ? count($arr) : (int)$max;
	$brr = array();								//除去空的元素,最终元素个数小于等于max
	$count = 0;									//使用新数组去掉旧数组的空值
	$flag = false;								//假设没有相同处
	$same = 0;									//假设相同值位于第一位
	//第一个循环:去除空值和检查是否有相同值,如果有则记下索引值
	for($i=0; $i < count($arr); $i++)
	{
		$brr[$count] = $arr[$i];
		if($brr[$count][0] == $new_value[0]){
			$flag = true;
			$same = $count;
		}
		$count++;
		if($count >= $max)	break;				//最大不能超过max
	}
	//第二个循环:要么增加,要么移动
	//思路:首先用flag判断是否有相同,如果有相同只需将其移到最前0也可以;如果没有只需增加时判断长度2种
	//增加的条件是:flag==false;brr.length<max
	//其余的都是移动即flag==false时的满长整体后移,部分后移和flag==true时的满长整体后移,部分后移。
	//但是只需要保证(移动)brr[brr.length-1]=value即可
	if($flag == false && count($brr) < $max)	//增加
	{
		$brr[count($brr)] = $new_value;
	}else{
		for($i=0; $i<count($brr)-1; $i++){
			if($i >= $same){					//不管找没找到都给我前移一位,其实它是分了2种情况合并了的
				$brr[$i] = $brr[$i+1];
			}
		}
		$brr[count($brr)-1] = $new_value;		//目的就是移动,不会有增加的,所以只需要设置一个值
	}
	return $brr;
}
$old = array(array('first', array('a', 'b')), array('second', 'c, d'), array('third', true));
$new = arr_queue($old, array('second', 'c, d'));
p($new);
$new = arr_queue($old, array('second', 'c, d'), 2);
p($new);

function p($var)
{
	echo "<pre>";
	if($var === false)
	{
		echo 'false';
	}else if($var === ''){
		print_r("''");
	}else{
		print_r($var);
	}
	echo "</pre>";
}


简单测试了,暂未发现问题。



本文地址:http://blog.zhengshuiguang.com/php/cookie-queue.html

转载随意,但请附上文章地址:-)

标签:cookie js array queue 数组队列

相关文章

评论已关闭