Php 搜索相似对象的数组

Php 搜索相似对象的数组,php,arrays,Php,Arrays,给定如下数组: $array = array( 0 => array ( 0 => 35, 1 => 30, 2 => 39 ), 1 => array ( 0 => 20, 1 => 12, 2 =

给定如下数组:

$array = array( 
            0 => array (
               0 => 35,
               1 => 30, 
               2 => 39
            ),
            1 => array (
               0 => 20,
               1 => 12, 
               2 => 5
            ),
            ...

            n => array (
               0 => 10,
               1 => 15, 
               2 => 7
            ),
         );
我需要在数组中找到更接近给定参数的条目

find($a, $b, $c) {
  //return the closer entry to the input
}
对于更接近的条目,我指的是与输入中给出的值更接近的条目,例如,通过(19,13,3),它应该返回$array[1]

目前我进行计算的方式是在整个数组中循环,保留一个变量$distance(从-1开始),以及一个临时的$result变量。对于每个元素,我计算距离

$dist = abs( subarray[0] - $a ) + abs ( subarray[1] - $b ) + abs( subarray[2] - $c ) 
如果计算的距离等于-1或小于循环外的变量$distance,我将新的距离分配给变量,并将相应的数组保存在$result变量中。在循环结束时,我得到了我需要的值

此外,其中一个值可以为空:例如,(19,13,false)仍应返回$array[1],然后计算应忽略缺少的参数-在这种情况下,距离计算为

$dist = abs( subarray[0] - $a ) + abs ( subarray[1] - $b );
忽略子数组[2]和$c的值

问题是,即使我的代码正常工作,执行起来也花了太多时间,因为数组的大小很容易增加到数十万个元素。我们仍然在谈论毫秒,但出于各种原因,这仍然是不可接受的。
为了节省时间,有没有更有效的方法来执行此搜索?

我基本上使用了接近度的概念(每个数组的总距离较小)并返回了该值。代码的编写方式可以在许多例程中得到很好的改进

PS:我没有使用高级功能或其他东西,因为您担心性能问题。这是我能在短时间内完成的最简单的例行程序

$array = array(
    0 => array (
        0 => 35,
        1 => 30,
        2 => 39
    ),
    1 => array (
        0 => 20,
        1 => 12,
        2 => 5
    ),
);

$user = array(19,13,3);

function find($referencial, $input){
    $totalRef = count($referencial);
    if (is_array($referencial)){
        for ($i = 0; $i < $totalRef; $i++) {
            if (is_array($referencial[$i])){
                $totalSubRef = count($referencial[$i]);
                $proximity = array();
                for ($j = 0; $j < $totalSubRef; $j++) {
                    $proximity[$i] += abs($referencial[$i][$j] - $input[$j]);
                }
                if ($i > 0){
                    if ($maxProximity['distance'] > $proximity[$i]) {
                        $maxProximity['distance'] = $proximity[$i];
                        $maxProximity['index'] = $i;
                    }
                } else {
                    $maxProximity['distance'] = $proximity[$i];
                    $maxProximity['index'] = $i;
                }
            }
        }
        return $maxProximity;
    } else {
        exit('Unexpected referencial. Must be an array.');
    }
}

$found = find($array, $user);
print_r($found);
//Array ( [distance] => 4 [index] => 1 )
print_r($array[$found['index']]);
// Array ( [0] => 20 [1] => 12 [2] => 5 )
$array=array(
0=>数组(
0 => 35,
1 => 30,
2 => 39
),
1=>数组(
0 => 20,
1 => 12,
2 => 5
),
);
$user=数组(19,13,3);
函数find($referenceal,$input){
$totalRef=计数($reference);
if(是_数组($referenceal)){
对于($i=0;$i<$totalRef;$i++){
if(是_数组($referenceal[$i])){
$totalSubRef=count($referential[$i]);
$approxity=array();
对于($j=0;$j<$totalSubRef;$j++){
$approxity[$i]+=abs($referenceal[$i][$j]-$input[$j]);
}
如果($i>0){
如果($maxpression['distance']>$appression[$i]){
$maxpression['distance']=$appression[$i];
$MaxProximition['index']=$i;
}
}否则{
$maxpression['distance']=$appression[$i];
$MaxProximition['index']=$i;
}
}
}
返回$maxproxity;
}否则{
exit('意外引用。必须是数组');
}
}
$found=find($array,$user);
打印(已找到);
//数组([距离]=>4[索引]=>1)
打印($array[$found['index']]);
//数组([0]=>20[1]=>12[2]=>5)

自定义函数-也许有更好的方法,但请查看:

简言之:

搜索所有项目,并按百分比查找它检查的数字($mArray[0…3])与您给出的数字($mNumbersToFind[0…3])之间的差异。添加(每个元素的)所有三个数字的可能性-查找最大值-保留位置并返回数组

$array = array( 
            array (
               0 => 13,
               1 => 15, 
               2 => 4
            ),
            array (
               0 => 20,
               1 => 12, 
               2 => 5
            ),

            array (
               0 => 13,
               1 => 3, 
               2 => 15
            ),
         );


$mNumbersToFind = array(13,3,3);

$mFoundArray = find($mNumbersToFind, $array);

echo "mFinalArray : <pre>";
print_r($mFoundArray);


function find($mNumbersToFind, $mArray){

    $mPossibilityMax = count($mNumbersToFind);
    $mBiggestPossibilityElementPosition = 0;
    $mBiggestPossibilityUntilNow = 0;


    foreach($mArray as $index => $current){

        $maxPossibility = 0;

        foreach($current as $subindex => $subcurrent){



            $mTempArray[$index][$subindex]['value'] = $subcurrent - $mNumbersToFind[$subindex];

            $percentChange = (1 - $mTempArray[$index][$subindex]['value'] / $subcurrent) * 100;
            $mTempArray[$index][$subindex]['possibility'] = $percentChange;
            $maxPossibility += $percentChange/$mPossibilityMax;


        }


        $mTempArray[$index]['final_possibility'] = $maxPossibility;

        if($maxPossibility > $mBiggestPossibilityUntilNow){
            $mBiggestPossibilityUntilNow = $maxPossibility;
            $mBiggestPossibilityElementPosition = $index;
        }



    }

    echo "mTempArray : <pre>"; // Remove this - it's just for debug
    print_r($mTempArray); // Remove this - it's just for debug

    return $mArray[$mBiggestPossibilityElementPosition];
}
最终输出:

mTempArray :
Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [value] => 0
                    [possibility] => 100
                )

            [1] => Array
                (
                    [value] => 12
                    [possibility] => 20
                )

            [2] => Array
                (
                    [value] => 1
                    [possibility] => 75
                )

            [final_possibility] => 65
        )

    [1] => Array
        (
            [0] => Array
                (
                    [value] => 7
                    [possibility] => 65
                )

            [1] => Array
                (
                    [value] => 9
                    [possibility] => 25
                )

            [2] => Array
                (
                    [value] => 2
                    [possibility] => 60
                )

            [final_possibility] => 50
        )

    [2] => Array
        (
            [0] => Array
                (
                    [value] => 0
                    [possibility] => 100
                )

            [1] => Array
                (
                    [value] => 0
                    [possibility] => 100
                )

            [2] => Array
                (
                    [value] => 12
                    [possibility] => 20
                )

            [final_possibility] => 73.333333333333
        )

)
mFinalArray : 
Array
(
    [0] => 13
    [1] => 3
    [2] => 15
)