【问题标题】:Unclear Javascript programming pattern (functions). Why the results differ?不明确的 Javascript 编程模式(函数)。为什么结果不同?
【发布时间】:2017-08-12 13:50:04
【问题描述】:

在 Chrome 控制台中我有一个字符串:

var string = 'john, john, bob, nina, colin, bob, luck, robert, nina, john, jack';

然后使用两种看起来与我相同的方法对其进行修改并分配一个新值:

第一种方法:

var string2 = string.split(", ").filter(function(value, index, array){
    return index === array.indexOf(value);
}).join(', ');

第二种方法:

var string3 = string.split(", ").filter(function(value, index, array){
    if(index === array.indexOf(value)) return index;
}).join(', ');

这两种方法应该怎么做:

  1. 将字符串分别转换为每个单词的数组。
  2. 过滤数组,使不存在重复值。
  3. 将数组转回字符串格式。

我希望 string2 和 string3 的值是:

"john, bob, tony, nina, colin, luck, robert, jack"

它们应该严格相同(根据我的逻辑)。

我实际得到的:

string2 = "john, bob, tony, nina, colin, luck, robert, jack";
string3 = "bob, tony, nina, colin, luck, robert, jack"

第二个字符串中缺少“John”。

我已经检查过的内容:

  1. 严格比较 (===),即在 if-statement () 对于第一个“john”是正确的。
  2. 既索引(参数 函数)和第一个“约翰”的值的索引是 0 符合预期。

我的问题:

请解释一下,为什么结果不同?

【问题讨论】:

  • 第一个没有意义。您必须始终从 filter 谓词函数返回一个布尔值 - 有时不是 undefined,有时是数字。
  • 您的“我实际得到的”结果看起来是相反的。
  • 1.我从这里得到了用于 string2 的函数:stackoverflow.com/questions/16843991/… 2。由于错误,交换了帖子中的函数。现在是正确的。
  • 您的第二种方法对我来说很好,不会返回重复项:string3 == "john, bob, nina, colin, luck, robert, jack"。我不确定你的预期结果是从哪里来的。

标签: javascript arrays string function


【解决方案1】:

你的第二个例子:

var string2 = string.split(", ").filter(function(value, index, array){
    if(index === array.indexOf(value)) return index;
}).join(', ');

if(index === array.indexOf(value)) return index; 这行写错了。

如果是index === array.indexOf(value),那将返回index,如果不是,则什么也没有。您需要返回truefalse

在 JavaScript 中,除0 之外的所有数字都转换为true,并且0 转换为false。因此,如果index0,那么您基本上返回的是false 而不是true

这是正确的代码:

var string2 = string.split(", ").filter(function(value, index, array){
    if(index === array.indexOf(value)) return true;
    else return false;
}).join(', ');

【讨论】:

  • “正确的代码”是多余的,以防只是重新调整比较结果。
  • @NinaScholz 他问有什么不同。第二个实际上是错误的,因此通过将其更正为他想要的样子,它们现在基本上是相同的。
  • “正确的代码”在else 的情况下缺少return false。依赖 undefined 是一个虚假值与 OP 落入的糟糕风格相同。
  • 还是乱码,if (...) return true; else return false;
  • @NinaScholz 显然。我正在纠正他的第二个例子,所以它看起来仍然像他的第二个例子。第一个例子会更好。
【解决方案2】:

你的结果是相反的。第一个代码块是消除“John”的代码块。 (已编辑问题以更正此问题)

对于string3,它消除了“John”,因为它返回“John”索引的唯一时间是“John”位于索引0,这是一个虚假值,所以“John”不会包含在结果中。

如果你返回一个布尔值会更清楚,就像在工作示例中一样,所以当值本身是假的时你不需要处理问题。

【讨论】:

    【解决方案3】:
    if (index === array.indexOf(value)) return index; // returns 0, at index 0,
                                                      // should return true
    

    return index === array.indexOf(value);
    

    这只是第一种情况下索引为零的问题,您返回索引为零,这会将Array#filter解析为false,而它应该是true,就像在第二种情况下一样。

    【讨论】:

    • 这就是问题所在!所以,我只需要返回 value 而不是 index?谢谢你,@Nina Scholz!
    • @Eduard 不,您既不应该返回值也不应该返回索引。你应该返回一个布尔值。
    • @bergi 如果我返回 value 它会起作用(尽管我知道它在语义上不正确)。因此,如果我继续使用 .fiter(),就没有正确 的方法。然后我应该将 .filter() 函数换成别的东西吗?
    • @Eduard 你返回true,检查我的答案。
    • @Eduard 返回value 可能适用于您的特定情况,但它不正确。我再说一遍:filter 期望回调返回一个布尔值(真或假)。其他任何东西都将被转换为一个。虚假值(如index 0 或空字符串value)会弄乱结果。因此,如果您坚持使用if 声明,请使用return checkif (check) return true; else return false;
    猜你喜欢
    • 2012-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-27
    • 1970-01-01
    相关资源
    最近更新 更多