【问题标题】:Sort array1 by array2 with SIMILAR key matches and not EXACT key matches使用 SIMILAR 键匹配而不是 EXACT 键匹配对 array1 按 array2 排序
【发布时间】:2011-06-18 00:09:31
【问题描述】:

我希望 $Array2 中的歌曲标题按照 $Array1 的相同顺序排序,而不会丢失 $Array2 中的值。 $Array2 中的值应遵循 $Array2 中每个键的新顺序。我相信我提供的当前功能是一个坚实的开始......

我有两个数组(请注意每个数组的区别):

  1. $Array1 是用户输入的数据。
  2. $Array2 是查找的数据 类似于的外部源 $Array1 但不精确。

例如...

$Array1 包含:

大批 ( [0] => 3oh!3 - 不要相信我 [1] => 泰勒斯威夫特 - 你属于我 [2] => 肖恩·金斯顿 - 燃烧的火焰 [3] => 绿日 - 了解你的敌人 [4] => 凯莉克拉克森 - 走了 )

$Array2 包含:

大批 ( [泰勒斯威夫特 - 你属于我] => bbbbbb [肖恩金斯顿 - 燃烧] => cccccc [凯莉克拉克森 - 走了] => eeeeee [3OH!3- Don't Trust Me 歌词] => aaaaaa [绿日知敌官方] => dddddd )

我已经在这个网站上找到了一个已启动的功能:

function sortArrayByArray(array $toSort, array $sortByValuesAsKeys)
{
    $commonKeysInOrder = array_intersect_key(array_flip($sortByValuesAsKeys), $toSort);
    $commonKeysWithValue = array_intersect_key($toSort, $commonKeysInOrder);
    $sorted = array_merge($commonKeysInOrder, $commonKeysWithValue);
    return $sorted;
}

不过……

$sortArray = sortArrayByArray($Array2, $Array1);
print_r($sortArray);

$sortArray 只返回两个结果:

Array
(
    [Sean Kingston - Fire Burning] => cccccc
    [Kelly Clarkson - Gone] => eeeeee
)

【问题讨论】:

  • 这是因为该函数专门匹配值,并且没有考虑不同的情况,例如“3OH!3”与“3oh!3”。这真的是一个正则表达式问题,你还有一首没有破折号和一个额外单词的绿日歌曲......在 php 中没有 4 行函数
  • 一种可能的方法:(1) 从所有字符串中去除所有非字母数字字符 (2) 转换为小写 (3) 找到最长的公共子字符串,并拒绝 LCS 小于 50% 的任何内容正在考虑的最短字符串。这可能适用于您的示例,但不适用于更混乱的数据。
  • @Keoki Zee 这是链接:stackoverflow.com/questions/348410/…@Trey 我无法控制从 $Array2 中的外部源查找的歌曲标题,但是它们是在外部源上格式化的。
  • @Frank Farmer 你对这样的事情有什么看法?点击链接,php.net/manual/en/function.similar-text.php#62715

标签: php sorting


【解决方案1】:

这里有一个解决方案:

<?php

$array1 = array(
  0 => '3oh!3 - Don\'t Trust me',
  1 => 'Taylor Swift - You Belong with me',
  2 => 'Sean Kingston - Fire Burning',
  3 => 'Green Day - Know Your Enemy',
  4 => 'Kelly Clarkson - Gone',
);

$array2 = array(
  'Taylor Swift - You Belong With Me' => 'bbbbbb',
  'Sean Kingston - Fire Burning' => 'cccccc',
  'Kelly Clarkson - Gone' => 'eeeeee',
  '3OH!3- Don\'t Trust Me lyrics' => 'aaaaaa',
  'Green Day Know Your Enemy Official' => 'dddddd'
);


// Find matching song titles (case insensitive).
$tmp = array_values(array_uintersect($array1, array_flip($array2), 'strcasecmp'));

if ( ! empty($tmp) )
{
  // Generate the array.
  $matches = array_flip(array_uintersect(array_flip($array2), $tmp, 'strcasecmp'));

  print_r($matches);
}
else
  echo 'No matches found.';

?>

这将输出:

Array
(
    [Taylor Swift - You Belong With Me] => bbbbbb
    [Sean Kingston - Fire Burning] => cccccc
    [Kelly Clarkson - Gone] => eeeeee
)

其他 2 个匹配项并非 100% 相同。正如其他人所建议的那样,您可以使用similar_text() 或其他函数来确定两个字符串的相似程度。如果您想这样做,您可以在 array_uintersect 调用中更改 'strcasecmp' 并编写您自己的函数,然后使用 similar_text(或其他函数)来决定这些值是否确实相交或不是。

【讨论】:

  • 您能否提供一个使用相似度为 75% 的similar_text() 函数的示例??
  • @w3dgie - 目前我没有可以分享的示例。一会儿我会看看我能想出什么。
  • 我想不通!我会等待你的答复。到目前为止,您提供了巨大的帮助! :)
  • 我已经写了这个函数:function checkSimilar($str1, $str2){ similar_text($str1, $str2, $percent); if($percent &gt; 75){ echo $str2; } else{ echo "bad match"; } }我如何将它应用到其余部分?
【解决方案2】:

尝试使用类似Levenshtein distancesimilar_text 的函数来比较数组中的字符串。您只需要确定一个尽可能准确匹配且误报最少的阈值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-28
    • 2012-09-02
    • 1970-01-01
    相关资源
    最近更新 更多