title: Compare arrays and search for matching values
body: <p>I have 2 arrays, <code>$arr1</code> and <code>$arr2</code>:</p>
  
  <p><code>$arr1</code> is a list of columns that I expect to read from an excel file, <code>$arr2</code> is the array of columns that were actually found.</p>
  
  <p>Sometimes the uploaded file contains</p>
  
  <ul>
  <li>Misspelled column names</li>
  <li>Columns in a different order</li>
  <li>Could be missing some columns</li>
  <li>Also, the column names might contain letters in a different charset (ex. a greek 'M' that looks like a latin <em>M</em> but cannot be accounted as the same).</li>
  </ul>
  
  <p>Lets say, for example, that we have the following 2 arrays: </p>
  
  <pre><code>$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');
  </code></pre>
  
  <p>I need to compare the 2 arrays and save the position of the matching elements to a 3rd array:</p>
  
  <pre><code>$arr3 = ([0]=&gt;0, [1]=&gt;1, [2]=&gt;3, [3]=&gt;5, [4]=&gt;6, [5]=&gt;...);
  </code></pre>
  
  <p>displaying the position of each matched element of <code>$arr1</code> in <code>$arr2</code>.</p>
  
  <p>By 'matching' I mean all elements that are identical (ex. <strong>Action</strong>), or partially the same (ex. <strong>Test</strong> &amp; <strong>Tes</strong>, ) and also those elements that are alike but are in different case (ex. <strong>Foo</strong> &amp; <strong>foo</strong>, <strong>Bar</strong> &amp; <strong>bar</strong>).</p>
  
  <p>I posted <a href="https://stackoverflow.com/questions/16153695/"><strong>this question</strong></a> a few days ago and I got a good answer but after several tests with more sample data I've found that it doesn't always work as expected.</p>
  
  <p>So after more searching I found the <a href="http://php.net/manual/en/function.levenshtein.php" rel="nofollow noreferrer"><strong>levenshtein</strong></a> function so I did a combination that first checks for an exact match and if not found, then tries to find the closest match. Now, the problem is that some columns have similar names, ex. <strong>Catlevel1</strong>, <strong>Catlevel2</strong>,...,<strong>Catlevel6</strong>. So if <strong>Catlevel2</strong> is missing, it will be matched with the last &amp; most similar column which is <strong>Catlevel6</strong>.</p>
  
  <p>This is what I have so far:     </p>
  
  <pre><code>foreach($all_columns as $i =&gt; $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 =&gt; $val2) {
              if($val1&lt;&gt;'' &amp;&amp; $val2&lt;&gt;'') {
                  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 =&gt; $value) {
      $found = wordMatch($value, $arr2, 2);
      $pos = array_search($found, $_SESSION['found_columns']); 
      $_SESSION['found_column_positions'][$i] = $pos;
      $i++;
  }
  </code></pre>
  
  <hr/>
  
  <pre><code>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 &lt;= $shortest || $shortest &lt; 0) {
              $closest  = $word;
              $shortest = $lev;
          }
      }
      if($shortest &lt;= $sensitivity){
          return $closest;
      } else {
          return 0;
      }
  }
  </code></pre>
  
  <p><hr/>
  Is there a better way to compare 2 arrays, find the closest value matches and save the matching value key to 3rd array to use as a key reference between the 2 arrays?</p>