4

私は2つの配列を持ってい$arr1ます$arr2

$arr1は、Excel ファイルから読み取ると予想される列のリストです$arr2。実際に見つかった列の配列です。

アップロードされたファイルに

  • 列名のスペルミス
  • 異なる順序の列
  • 一部の列が欠落している可能性があります
  • また、列名には異なる文字セットの文字が含まれている場合があります (たとえば、ギリシャ語の 'M' はラテン語の M のように見えますが、同じと見なすことはできません)。

たとえば、次の 2 つの配列があるとします。

$arr1 = array('Action', 'LotSize', 'QuantityMinimum', 'SupplierName', 'SPN',
 'PartNumExt', 'UOM', 'ListPrice', 'MPN', 'MFrName', 'CatLevel1', 'CatLevel2',
 'CatLevel3', 'CatLevel4', 'CatLevel5', 'CatLevel6', 'AcctLevel1', 'AcctLevel2', 
 'AcctLevel3', 'AcctLevel4', 'AcctLevel5', 'AcctLevel6', 'Desc1', 'Desc2', 'PicName',
 'SupplierURL', 'CatPart','TechSpec', 'Kad');    

$arr2 = array('Action', 'LotSze', 'QuantityMinimum', 'SupplierName', 'SPN',
 'PartNumEx', 'UOM', 'ListPric', 'MPN', 'MfrName', 'CatLevel1', 'CatLevel2',
 'CatLevel3', 'CatLevel4', 'AcctLevel1', 'AcctLevel2', 'AcctLevel3', 'AcctLevel4',
 'Desc1', 'Desc2', 'PicName', 'SupplierURL', 'CatPart');

2 つの配列を比較し、一致する要素の位置を 3 番目の配列に保存する必要があります。

$arr3 = ([0]=>0, [1]=>1, [2]=>3, [3]=>5, [4]=>6, [5]=>...);

$arr1inの一致した各要素の位置を表示し$arr2ます。

「一致する」とは、同一のすべての要素 (例: Action )、または部分的に同じ (例: Test & Tes )、および類似しているが大文字と小文字が異なる要素 (例: Foo & fooBar &バー)。

数日前にこの質問を投稿し、良い回答を得ましたが、より多くのサンプル データを使用していくつかのテストを行った結果、常に期待どおりに機能するとは限らないことがわかりました。

したがって、さらに検索した後、レーベンシュタイン関数を見つけたので、最初に完全一致をチェックし、見つからない場合は最も近い一致を見つけようとする組み合わせを行いました。さて、問題は、いくつかの列が似たような名前を持っていることです。Catlevel1Catlevel2、...、Catlevel6。したがって、Catlevel2が欠落している場合、最後で最も類似した列であるCatlevel6と一致します。

これは私がこれまでに持っているものです:

foreach($all_columns as $i => $val1) {
    $result = null;
    // Search the second array for an exact match, if found
    if(($found = array_search($val1,$_SESSION['found_columns'],true)) !==false) {
        $result = $found; 
    } else {
        // Otherwise, see if we can find a case-insensitive matching string 
        //where the element from $arr2 is found within the one from $arr1
        foreach( $_SESSION['found_columns'] as $j => $val2) {
            if($val1<>'' && $val2<>'') {
                if( stripos( $val1, $val2) !== false ) {
                    $result = $j;
                    break;
                } else {
                    $notfound .= $val1.', ';
                    break;
                }
            }
        }
    }
    $_SESSION['found_column_positions'][$i] = $result;
}

/*****ALTERNATIVE METHOD USING levenshtein*****/
$i=0;
foreach($all_columns as $key => $value) {
    $found = wordMatch($value, $arr2, 2);
    $pos = array_search($found, $_SESSION['found_columns']); 
    $_SESSION['found_column_positions'][$i] = $pos;
    $i++;
}

function wordMatch($input, $array, $sensitivity){
    $words = $array;
    $shortest = -1;
    foreach ($words as $word) {
        $lev = levenshtein($input, $word);
        if ($lev == 0) {
            $closest = $word;
            $shortest = 0;
            break;
        }
        if ($lev <= $shortest || $shortest < 0) {
            $closest  = $word;
            $shortest = $lev;
        }
    }
    if($shortest <= $sensitivity){
        return $closest;
    } else {
        return 0;
    }
}


2 つの配列を比較し、最も近い値の一致を見つけ、一致する値のキーを 3 番目の配列に保存して、2 つの配列間のキー参照として使用するより良い方法はありますか?

4

6 に答える 6

1

Following script will do the work.

<?php
$arr1 = array('Action', 'LotSize', 'QuantityMinimum', 'SupplierName', 'SPN',
 'PartNumExt', 'UOM', 'ListPrice', 'MPN', 'MFrName', 'CatLevel1', 'CatLevel2',
 'CatLevel3', 'CatLevel4', 'CatLevel5', 'CatLevel6', 'AcctLevel1', 'AcctLevel2', 
 'AcctLevel3', 'AcctLevel4', 'AcctLevel5', 'AcctLevel6', 'Desc1', 'Desc2', 'PicName',
 'SupplierURL', 'CatPart','TechSpec', 'Kad');    

$arr2 = array('Action', 'LotSze', 'QuantityMinimum', 'SupplierName', 'SPN',
 'PartNumEx', 'UOM', 'ListPric', 'MPN', 'MfrName', 'CatLevel1', 'CatLevel2',
 'CatLevel3', 'CatLevel4', 'AcctLevel1', 'AcctLevel2', 'AcctLevel3', 'AcctLevel4',
 'Desc1', 'Desc2', 'PicName', 'SupplierURL', 'CatPart');

$arr3 = array();

foreach($arr1 as $key=>$val)
{
    $arr3[$key] = array_search($val, $arr2);
}

print_r($arr3);
?>
于 2014-08-27T05:04:48.807 に答える
0

これがオプションかどうかはわかりませんが、ユーザーがページを管理して各ヘッダーの可能な値を教えてくれる同様のシステムがあります。次に、システムはアップロードを試みる前に、標準の承認済みヘッダーに変換します。ユーザーが作成したマッピングに基づいています。これにより、ユーザーが毎回マップする必要がなくなります。アップロードしようとしている列のいずれにもエントリがない場合、アップロードはエラーをスローします。

頑張ってください!

于 2013-05-13T14:56:11.550 に答える
0
?php
$arr1 = array('Action', 'LotSize', 'QuantityMinimum', 'SupplierName', 'SPN',
'PartNumExt', 'UOM', 'ListPrice', 'MPN', 'MFrName', 'CatLevel1', 'CatLevel2',
'CatLevel3', 'CatLevel4', 'CatLevel5', 'CatLevel6', 'AcctLevel1', 'AcctLevel2', 
'AcctLevel3', 'AcctLevel4', 'AcctLevel5', 'AcctLevel6', 'Desc1', 'Desc2', 'PicName',
'SupplierURL', 'CatPart','TechSpec', 'Kad');  

$arr2 = array('Action', 'LotSze', 'QuantityMinimum', 'SupplierName', 'SPN',
'PartNumEx', 'UOM', 'ListPric', 'MPN', 'MfrName', 'CatLevel1', 'CatLevel2',
'CatLevel3', 'CatLevel4', 'AcctLevel1', 'AcctLevel2', 'AcctLevel3', 'AcctLevel4',
'Desc1', 'Desc2', 'PicName', 'SupplierURL', 'CatPart');

$arr3 = array_intersect($arr1, $arr2));
echo arr3 ;

?>
于 2013-06-05T13:51:55.420 に答える
0
<?php
$arr1 = array('Action', 'LotSize', 'QuantityMinimum', 'SupplierName', 'SPN',
'PartNumExt', 'UOM', 'ListPrice', 'MPN', 'MFrName', 'CatLevel1', 'CatLevel2',
'CatLevel3', 'CatLevel4', 'CatLevel5', 'CatLevel6', 'AcctLevel1', 'AcctLevel2', 
'AcctLevel3', 'AcctLevel4', 'AcctLevel5', 'AcctLevel6', 'Desc1', 'Desc2', 'PicName',
'SupplierURL', 'CatPart','TechSpec', 'Kad');  

$arr2 = array('Action', 'LotSze', 'QuantityMinimum', 'SupplierName', 'SPN',
'PartNumEx', 'UOM', 'ListPric', 'MPN', 'MfrName', 'CatLevel1', 'CatLevel2',
'CatLevel3', 'CatLevel4', 'AcctLevel1', 'AcctLevel2', 'AcctLevel3', 'AcctLevel4',
'Desc1', 'Desc2', 'PicName', 'SupplierURL', 'CatPart');

$arr3=array();

for($i = 0; $i < count($arr1) ;$i++)
{ 
$max=0;
$result=0;
for ($j=0; $j< count($arr2) ; $j++)
{
     $percent=find($arr1[$i],$arr2[$j]);
     if ($percent>$max) 
             { $max= $percent;
               $result=$j; 
            } 

 }
 $arr3[$i]=$result;
}
for($i = 0; $i < count($arr3) ;$i++)
    echo "[".$i."]=> ".$arr3[$i].", ";

function find($a,$b)
{
similar_text($a, $b, $percent);
return $percent;
}
?>

これは完全なプログラムです。それが役に立てば幸い!

于 2013-06-05T13:27:26.693 に答える
0

array_search()を使用した非常に単純なアルゴリズムは次のとおりです。

$mapping = [];

foreach ($arr1 as $i => $value)
{
    $actualKey = array_search($value, $arr2);

    if (false !== $actualKey)
    {
        $mapping[$i] = $actualKey;
    }
}

array_search($needle, $haystack)

array_search — 指定された値の配列を検索し、成功した場合は対応するキーを返します [それ以外の場合は false]

于 2013-08-20T12:51:45.497 に答える