去除重复数据,对多维数组排序 之 php

这几天一直在做一个需求,要求找出数据库相连的电话号码,相连的号码要求可以是前4位或前3位,可由参数控制的。如下所示:

要求找出4位4连号,输入特征号码为:1256 ;

则应该找出以下号码:+++++++ 代表手机号码中的任意前7位

+++++++1253,+++++++1254,+++++++1255,+++++++1256,+++++++1257,+++++++1258,+++++++1259

数据库为oracle,想了很久都没想到在SQL语句下功夫的方法,据说同事想到了,但经测试没有成功,待想到了数据库方法再贴.

下面写出我在PHP代码中处理的方法:

假设现在已经生成了一个二维数组,接下来我们要对这个数组中的数据进行处理,以得到要求的数据。

先将代码贴下来吧,回家理下思路

 

/*
 * add by 20071030 yangxs 添加对家庭连号的查询
 * @notes 本函数可用于对一二维数组中的数据筛选,如:一组号码尾部的几位与一个特征字符串比较,
 并得到在这组号码中与特征字符串前后(+/-1的号码,可进位,可控制是否有重号)相同的号码。
 例:$arrSrc = array(0    => array('number') => '13028101004'),
                      1    => array('number') => '13928101000'),
                     2    => array('number') => '13228101001'),
                     3    => array('number') => '13028101003'),
                     4    => array('number') => '13228101002'),
                     5    => array('number') => '13028100997'),
                     6    => array('number') => '13328100998'),
                     7    => array('number') => '13028100999'),
                     8    => array('number') => '13128101002'),
                     9    => array('number') => '13628101002'),
                     10    => array('number') => '15228100586'),
                     11    => array('number') => '13028101996'),
                     12    => array('number') => '15688899999'),
                     13    => array('number') => '15105021006'),
                     14    => array('number') => '15105021007'),
                     15    => array('number') => '15105021009'),
                     );
    $t_character    = '998';
    $repeat         = true;
    $intLinkNum     = 8; 
    则我们要得到的数据应该是:
    $arrSrc = array(0    => array('number') => '13028101996 '),
                      1    => array('number') => '13028100997 '),
                     2    => array('number') => '13328100998 '),
                     3    => array('number') => '13028100999 '),
                     4    => array('number') => '13928101000'),
                     5    => array('number') => '13228101001'),
                     6    => array('number') => '13228101002'),
                     7    => array('number') => '13128101002'),
                     8    => array('number') => '13628101002'),
                     9    => array('number') => '13028101003'),
                     10    => array('number') => '13028101004')
                     );
    也就是在998前后的数据,且相邻的数据之差应该等于1,如果中间的号码没有找到,则不再向那个方向继续查找
    如下程序     
                          
 * @param object $conn 数据库连接对象
 * @param int    $intLinkNum 要找到的号码数量 
 * @param string $t_character 特征字符串
 * @param array  $arrSrc 源数组
 * @param boolea $repeat = true 是否可以包含重复的号码
 * @return array 成功则返回一个满足家庭连号条件的数组,失败则返回一个带有错误提示的数组
*
*/
function get_homelink_number($arrSrc,$t_character,$intLinkNum = 0,$repeat = true)
{
    
$arrResult        = array();        //最终满足条件的数组,如果没有则为出错信息如:array(0,'参数传递错误!');
    $arrMySrc        = array();        //将源数组处理后的数组,其中包含一个用于排序的元素sortval
    $arrChar        = array();        //特征字串数组,如传入为1258,则该数组内容为array(1256,1257,1258,1259) 等
    $strHaveChar    = '';            //将已经满足基本条件的号码特征字符记录
    $ifFound        = false;        //是否能找到尾部与特征字符串相同的数据
    $intCharLen        = strlen($t_character);//首先根据特征字符串的长度来得到要比较的尾数长度
    
    //检测传入参数

    if(empty($t_character|| count($arrSrc)<=0)
    {
        
$arrResult        = array(-1,'参数传递错误!');
        
return $arrResult;
    }    
    
    
//构造满足特征的字串数组,如:由998构造的数组为:array(998,999,997,1000,996,1001,995,1002,994,1003,993,1004,992,1005,991,1006,990)
    $arrChar[0]        = $t_character;
    
for($i =1;$i<=$intLinkNum;$i++)
    {
        
//向前加1 pow(10,$intCharLen)可以得到特征字符串进位的整数,如999+1 = 1000(10的3次方); 9999+1 = 10000(10的4次方)
        if(($t_character + $i)-pow(10,$intCharLen)>=0)
        {
//进位
            $arrChar[]    = substr('0000'.($t_character+$i),-($intCharLen+1)); //进位时向前多取一位
        }else
        {
            
$arrChar[]    = substr('0000'.($t_character+$i),-$intCharLen);
        }        
        
//向后减1
        if(($t_character - $i)>=0)
        {
//只包含大于0的情况,如果小于0则暂时不处理
            $arrChar[]    = substr('0000'.($t_character-$i),-$intCharLen);
        }    
    }
        
    
//重新构造满足基本条件的数组,即在    $arrSrc.[$i].number 的最尾的几位在特征字串数组里时,将$arrSrc.[$i]保存的新的数组里,并将当前元素的特征字符串保存,供后面排序使用
    foreach($arrSrc as $arr)
    {    
        
if(count($arr> 0)
        {
            
if((substr($arr['number'],-($intCharLen + 1)) - pow(10,$intCharLen)) <= $intLinkNum && (substr($arr['number'],-($intCharLen + 1)) - pow(10,$intCharLen)) >= 0)
            {
//取得当前号码的尾部字符串,如果当前号码的尾部 $intCharLen + 1 位 - 特征字符串进位的整数 >=0 且 <= $intLinkNum 时,表示该号码是特征字符串的进位号码
                $tailStr        = substr($arr['number'],-($intCharLen + 1));
            }
elseif((substr($arr['number'],-($intCharLen + 1)) - pow(10,$intCharLen))<0)
            {
//取得当前号码的尾部字符串,如果当前号码的尾部 $intCharLen + 1 位 - 特征字符串进位的整数 < 0 时,表示该号码是特征字符串的没有进位的号码
                $tailStr        = substr($arr['number'],-($intCharLen));
            }
            
            
//查看当前号码的尾部字符串是否在特征的字串数组,如果在则写入新的数组中
            if((count($arrChar> 0 && in_array($tailStr,$arrChar)))
            {
                
//查看当前号码的尾部字符串是否等于传入的特征字符串,等于则表示在源数组中能找到尾部与特征字符串相同的数据
                if($tailStr == $t_character)
                    
$ifFound = true;
                
$arr['sortval']        = $tailStr;//写一个可用于排序的元素
                $arrMySrc[]            = $arr;
            }
        }
    }
    
    
unset($arrChar,$arrSrc);
    
    
if($ifFound == false)
    {
        
$arrResult        = array(-1,'没有找到匹配的号码信息!');
        
return $arrResult;
    }
    
    
//排序
    usort($arrMySrc,'sort_char_query');
    
    
$strHaveChar        = '';
    
//检查是否为连续号码
    $k    = 0;    
    
for($i = 0,$h = 0,$j = count($arrMySrc); $i<$j$i++)
    {        
        
if($i == 0)
        {
            
$strHaveChar    =  $arrMySrc[$i]['sortval'];
            
$arrResult[$h++]    = $arrMySrc[$i];
            
$k                = 1;
            
continue;
        }
        
/*if(count($arrResult) == $intLinkNum)
        {
            break;
        }
*/
        
if($i >=1 && $strHaveChar != $arrMySrc[$i]['sortval']  && $strHaveChar+1 != $arrMySrc[$i]['sortval'])
        {
            
//$arrResult        = array();
            $strHaveChar    =  $arrMySrc[$i]['sortval'];
            
//$k                = 1;
        }elseif($repeat && $strHaveChar == $arrMySrc[$i]['sortval'])    //是否可以重复
        {
            
$arrResult[$h++]    = $arrMySrc[$i];                        
        }        
        
elseif($i>0 && $strHaveChar != $arrMySrc[$i]['sortval'])
        {            
            
$strHaveChar    =  $arrMySrc[$i]['sortval'];
            
$arrResult[$h++]    = $arrMySrc[$i];
            
$k                = $k + 1;    
        }
    }
    
    
if($k < $intLinkNum)
    {
        
$arrResult        = array(-1,'没有找到匹配的号码信息!');
    }    
    
return $arrResult;    
}
/*
 * add by 20071030 yangxs 自定义二维数组排序函数
 * @param array $arr1 前一数组元素
 * @param array $arr2 当前数组元素
 * @return int  返回是否要交换当前记录与前一记录
*
*/
function sort_char_query($arr1,$arr2)
{            
    
if ($arr1['sortval'== $arr2['sortval']) return 0;
    
return ($arr1['sortval'< $arr2['sortval'] ) ? -1 : 1;
}

 注释较多,主要是自己以后想用时方便,哈哈,希望各位看官在发现BUG或有什么新想法时不惜告诉我,我的

QQ:75323501

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值