【问题标题】:Remove similar strings from an array in Javascript从Javascript中的数组中删除相似的字符串
【发布时间】:2016-11-14 13:33:14
【问题描述】:

我有一个 类似字符串的数组,比如地标列表:

[“AB 街”、“AB 街”、“AB 街 XE”、“AB 街 X”、“AB 街道(XE)"]

每一个都代表一个地标“AB Street”。

我尝试了不同的方法,找到了一种删除多余空格和特殊字符的方法,但无法弄清楚如何缩短带有扩展名称的无关条目,这些条目无论如何都会导致相同的字符串。

删除空格和特殊字符的代码sn-p:

var landmarks = ["AB Street", "A B Street", "AB Street XE", "AB Street X", "AB Street(XE)"];
var formattedLandmarks = [];

landmarks.sort();
landmarks.forEach(function(location) {
  var key = location && location.toLowerCase();
  key = key.replace(/[.\/-]*/g, "");
  key = key.replace(/\(.*\)/i, "");
  key = key.replace(/[0-9, _-]*$/, "");
  key = key.replace(/[ \t]+/g, " ");
  key = key.toString().trim();
  key = key.charAt(0).toUpperCase() + key.slice(1);

  formattedLandmarks.push(key);
});

console.log(formattedLandmarks);

我希望算法将输出作为只有一个条目的数组返回:

[“AB 街”]

如果有人可以提供最佳方法和算法以实现预期输出(无论是通过 RegExp 还是其他方式),那将是非常棒的。

任何帮助都是可观的。

【问题讨论】:

  • 那么,关键模式应该由两个词组成?如果初始数组看起来像 [ "ABStreet", "AB Street XQ", "AB Street XEA", "AB Street(XE)"] 怎么办?应该如何看待它的预期结果?
  • 我认为您需要更详细地说明“类似类型的字符串”。对人类来说,是的,我们可以很容易地得出“AB Street”可能是一个有效的“类似词”。不幸的是,机器在模式识别方面不如我们聪明,它需要我们告诉他们要寻找什么样的模式。在您的示例中,“AB”也可能是类似的类型,因为它也确实出现在其他字符串中。
  • 不一定是两个字。对于您要求的那个,我希望它是“ABStreet”,在这种情况下。 @RomanPerekhrest
  • @SamuelToh 我同意你的说法,这正是我的困惑所在,如果它是不同排列和组合的结果,还是我应该选择最短的还是最长的,这将成为最佳实践。
  • 您最终可能会得到一个函数,该函数将 2 个字符串作为输入并返回 [0...1] 中的相似度得分,但您仍然必须决定 '足够体面的分数'门槛。可能与 PHP 函数 similar_text() 很接近,它显然已被移植到 JS here。不过,不确定这是否是满足您需求的正确算法。

标签: javascript arrays string replace duplicates


【解决方案1】:

你可以试试这样的:

逻辑

  • 按升序对数组进行排序
  • 将初始值设置为空白
  • 循环并检查当前值是否具有先前值。如果没有,则将其推送到数组中。

注意:您正在比较解析的值,因此您应该仅根据这些解析的值进行排序。

var array = ["AB Street", "A B Street", "AB Street XE", "AB Street X", "AB Street(XE)"];
var regex = /[^a-z]/gi;

var final = [];
array.sort(function(item1, item2){
  var _a = item1.replace(regex,"");
  var _b = item2.replace(regex,"");
  return _a > _b? 1: _a < _b ? -1: 0;
}).reduce(function(currentItem, nextItem) {
  var _p = currentItem.replace(regex, "");
  var _c = nextItem.replace(regex, "");
  if (_c.indexOf(_p)<0 || !currentItem) {
    final.push(nextItem);
  }
  return nextItem;
}, "")

console.log(final)

参考

【讨论】:

  • 你能给你给的变量取适当的名字吗,比如a,b,c。无法正确理解。
  • 非常好的答案,令人印象深刻! @PrernaJain 要了解正则表达式,请使用:regexr.com。要了解排序和归约,请在 Google 中找到 Array.prototype.sort() 和 Array.prototype.reduce()。 p 表示以前,c 表示当前。
  • @PrernaJain 我已经更新了我的答案并添加了参考链接。 @忍者,谢谢。
  • @Rajesh 非常感谢。算法工作得非常好,据我所知,它是最好的方法之一。
  • @TheNinja 感谢您提及参考资料。我知道数组原型和正则表达式,只是要求命名变量以使其更易于理解,即使对于新手也是如此。
猜你喜欢
  • 2015-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-02
  • 1970-01-01
  • 2023-01-10
  • 2023-01-09
相关资源
最近更新 更多