【问题标题】:Is there a way to count how many shared characters are between two strings using jQuery?有没有办法使用jQuery计算两个字符串之间有多少共享字符?
【发布时间】:2018-08-05 18:02:41
【问题描述】:

我希望能够比较两个键入的字符串并显示它们之间共享了多少个字母。

例如,如果一个输入得到 "dog" 字符串,而另一个输入得到 "door" 字符串。它将回显'2'(只有 "d""o" 在这两个字符串之间共享)。

但是如果一个字符串是 "door" 并且一个字符串是 "bloom" 它会回显'2'(而不是'1')。

有什么功能可以帮助这种操作吗?

【问题讨论】:

  • “有没有办法使用 jQuery 计算两个字符串之间有多少共享字符?” 没有。jQuery 是一个 DOM 操作函数库(以及偶尔的实用函数),仅此而已。 JavaScript,您使用它的语言,当然可以用于此。做你的研究,search 以获取有关 SO 的相关主题,并试一试。 如果您在进行更多研究和搜索后遇到困难并且无法摆脱困境,请发布您的尝试minimal reproducible example,并具体说明您卡在哪里。人们会很乐意提供帮助。祝你好运!
  • 如果共享超过 1 个字符,输出将如何显示?

标签: jquery arrays string search match


【解决方案1】:

您可以创建一个对象,对每个唯一字母(频率)进行计数,然后在与另一个输入中的字母匹配时减少该计数器。只有当计数器仍然为正时,才允许匹配。

该方法还将避免嵌套循环,因此具有更好的时间复杂度(请记住,indexOf 表示内部循环):

$(".1,.2").on("keyup", function() {
    const value1 = [...$(".1").val().toLowerCase().replace(/\s|-/g,'')],
        value2 = [...$(".2").val().toLowerCase().replace(/\s|-/g,'')],
        freq = {};
    value1.forEach(ch => freq[ch] = (freq[ch] || 0) + 1);
    var result = value2.reduce((acc, ch) => acc + (freq[ch] ? !!freq[ch]-- : 0), 0);
    $('.result').text(result + ' letters match!');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Write a word: <input class="1"><br/>
And another one: <input class="2"><br/>
<div class="result"></div>

说明

与您的代码相比,我有:

  • 使用 /\s|-/g 将两个替换合并为一个:这将一次性匹配任何空格或连字符。
  • 使用扩展运算符[... ] 将字符串拆分为字符数组。调用 split 也可以,但我喜欢这种较短的语法。
  • 引入了变量freq。它是一个普通对象,并为每个单独的字符获取一个属性。由于属性是唯一的,因此每个唯一字符仅存在一个属性。
  • forEach 循环将创建这些属性,并为其分配一个数字,以反映特定字符在 value1 中出现的次数。
  • 表达式(freq[ch] || 0) 首先计算freq[ch]。如果freq 还没有该字符ch 的属性,那么这将给出undefined,这是一个“虚假”值。然后逻辑 OR (||) 将启动并取 0 作为值。然后将+ 1 添加到其中,因此第一次出现的值为1。然后将其分配给freq[ch]。另一方面,如果该属性已经存在,它将具有 1 或更大的值,这是一个“真实”值,因此不会评估 || 0 并将 + 1 添加到当前值。这是 JavaScript 代码中经常使用的一种策略。因此,对于“门”的示例,一旦 forEach 完成,freq 将如下所示:

    {
        "d": 1,
        "o": 2,
        "r": 1
    }
    
  • reducevalue2 上被调用,它只是迭代value2 中的每个单独的字符并返回一个单个 值。该值以 0 开始(传递给 reduce 的最后一个参数),并作为第一个参数 acc 传递给回调。使用三元运算符,我们检查字符是否存在于freqfreq[ch] ?。如果是这样,则评估 !!freq[ch]-- 部分。这看起来有点复杂,但实际上并不难理解。 freq[ch]-- 给了我们freq[ch] 的值(value1 中出现的次数)然后递减它(--)。重要的是该值在减少发生之前被检索。然后对该值应用双重否定(!!):将数字转换为布尔值:非零为真,零为假。但是正如我们已经通过三元运算符知道它是非零的,这总是给我们true:这个布尔值然后再次强制转换为数字(1),因为它必须添加到acc。因此,当freq[ch] 不为零时,我们实际上将 1 添加到 acc。然后是三元运算符的另一部分,当freq[ch] 为零或根本不存在时启动:在这种情况下,我们将 0 添加到acc(无操作)。这个表达式被返回到reduce 内部,它再次将它作为acc 传递给下一次迭代,因此acc 对于每个匹配的字符都会递增。 reduce 返回 acc 的最后一个值,为我们提供最终结果。

【讨论】:

  • 哦,对不起,我想我写的时候喝醉了:))效果很好!谢谢!
  • 如果能在代码上加一些解释cmets就好了。再次感谢!
  • 添加了解释。
  • 太棒了。绝对精彩!非常感谢你!从中学到了很多!
【解决方案2】:

所以,这就是我最终得到的解决方案(cmets 真的很有帮助:)

var a = "dog";
var b = "door";
var c = a.split("").filter(function(val) {
return b.split("").indexOf(val) != -1;
});

c.length 现在将包含共享信件的数量。

希望它也对其他人有所帮助。

例子:

$(".1,.2").on("keyup", function() {
var value1 = $(".1").val().toLowerCase().replace(/\s/g,'').replace('-','');
var value2 = $(".2").val().toLowerCase().replace(/\s/g,'').replace('-','');
var result = value1.split("").filter(function(val) {
return value2.split("").indexOf(val) != -1;
});
$('.result').html(result.length + ' letters match!');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Write a word: <input class="1"><br/>
And another one: <input class="2"><br/>
<div class="result"></div>
  • 如果我输入“狗”和“门”。它会回显“3”而不是“2”。所以它还不是完全正确,但非常接近。

【讨论】:

    猜你喜欢
    • 2016-11-22
    • 2011-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-03
    • 2013-11-01
    相关资源
    最近更新 更多