【问题标题】:How to .join() arrays nicely如何很好地 .join() 数组
【发布时间】:2013-10-08 18:00:28
【问题描述】:

我发现Array.prototype.join() 方法在从数组构造字符串时非常有用,比如

"one two three".split(' ').join(', ');

但很多时候我想生成这样的字符串:

"one, two and three"

我使用的方法是这样的:

var parts = "one two three".split(' ');
parts.slice(0, parts.length-1).join(', ') + ' and ' + parts.slice(-1)

这会生成我想要的,但是我应该将其放入单独的函数中。

我喜欢单行,并且相信在 JS 中应该有更优雅的单行来完成这项任务。谁能给我一份?

编辑

请不要评论说编写不可读的代码是一种不好的做法。我要一个! :) 我从一个班轮中学到了很多关于语言结构的知识,因此有一种情况我看到了一种可能性。无意冒犯。

最终编辑 我很欣赏 Pavlo 的回答,因为它确实显示了一个班轮可以多么容易地成为一个漂亮的可读代码。因为我要求一个班轮,所以根据我的问题 h2ooooooo 获得最高分。

【问题讨论】:

  • 只有清晰简洁的衬里才是好的。我讨厌那些试图太聪明且难以阅读的代码。代码应该易于阅读以帮助维护。
  • 你可能会得到一个单行,但它会非常不可读且难以维护。
  • 我喜欢一个班轮,因为他们经常表现出高级的语言用法,我喜欢学习新事物。这不是我想在整个代码中放置一个衬里的情况。
  • 这个问题似乎是题外话,因为它是关于代码高尔夫
  • @DanielPryden 这不是问题,直到它成为问题。我们不知道范围,也许这是一个小项目。无需将事情过度复杂化。

标签: javascript arrays string


【解决方案1】:

它仍然是一个函数,但为什么不使用 prototype 呢?

Array.prototype.joinNice = function() {
    return this.slice(0, this.length-1).join(', ') + ' and ' + this.slice(-1);
}

"one two three".split(' ').joinNice();
//one, two and three

【讨论】:

  • 好吧,我会回答“为什么不呢?” with:一般来说,像这样扩展本机宿主对象是一个非常糟糕的主意。
  • 方便,理智,但最重要的是,由于您刚才提到的原因,这只是一般的坏建议。不仅“标准”可以创建类似的功能,任何其他脚本也可以这样做。基本上,这与全局变量相同的血液和痛苦。
  • @C5H8NNaO4 如果浏览器的实现方式稍有不同,您将会遇到一些有趣的惊喜/错误。如果您想要浏览器的默认值,最好将它们全部覆盖,然后用查找/替换重命名它们。
  • 为什么是slice(0, this.length - 1) 而不仅仅是slice(0, -1)
  • @h2ooooooo,that's a question for the language designers。您必须将原型扩展标记为不可枚举才能被for..in 循环忽略,但这样做不向后兼容,因此您仍然会失去浏览器支持。
【解决方案2】:

这个怎么样?

(parts = "one two three".split(" ")).slice(0, parts.length - 1).join(", ") + " and " + parts.slice(-1);

【讨论】:

  • 这永远不会通过代码审查...它完成了工作,但是需要维护它的程序员的理智要付出什么代价?
  • @lukas.pukenis 只是因为你知道它应该做什么,在你忘记了那个小事实并且需要重建它为什么这样写之后回来
  • @ratchetfreak 你说得很好。现在才过去了 3 个小时,而且是硬核!
  • +1,对我来说也很可读;仍然希望将其功能化。顺便说一句,parts.length - 1 可以只替换为 -1
【解决方案3】:

如果你想要一个班轮

"one, two and three"  

更通用一点..

function splitJoin (str,del,arr) {
    for (x=str.split (del),i=x.length;i--;x[i]+=(arr[i]||"")); return x.join("");
}

console.log (
    splitJoin ("one two three"," ", [", "," and "])
) //one, two and three

【讨论】:

  • @blesh 完全正确,改了,反正传统方式更短=)
【解决方案4】:
"one two three".split(' ').join(', ').replace(/^(.+),/, "$1, and")

(它在语法上更正确!) 虽然如果最后一部分本身包含逗号,它将无法按预期工作。

【讨论】:

  • $1, 更改为$1。它将输出one, two, and three 而不是one, two and three
  • @OlegV.Volkov 这与英语无关。请再次检查问题中的预期输出。
  • @thefourtheye,这是刻意的改变,从随附的文字中可以很容易地理解。我也相信,对于任何想要不带逗号的人来说,在我不牵手的情况下自己更改它是愚蠢的。
【解决方案5】:

我并不是说它很漂亮。或者在所有浏览器中都支持。

parts.reduce(function(val1, val2, i, arr) {return val1 + (i + 1 < arr.length ? ', ' : ' and ') + val2});

【讨论】:

    【解决方案6】:

    我对神秘解决方案的数量以及没有人使用 pop() 的事实感到惊讶:

    function splitJoin(source) {
        var array = source.split(' ');
        var lastItem = array.pop();
    
        if (array.length === 0) return lastItem;
    
        return array.join(', ') + ' and ' + lastItem;
    }
    
    splitJoin('one two three'); // 'one, two and three'
    splitJoin('one two');       // 'one and two'
    splitJoin('one');           // 'one'
    

    编辑:修改为适用于任何字符串。

    【讨论】:

    • 尽管要求单行 - 可读性的绝佳例子!谢谢!
    • +1 表示干净的解决方案,-1 表示意外的副作用。
    • @BoppreH,意外的副作用是什么?
    • @BoppreH 这并不重要,因为我们以任何方式在函数内部创建该数组 - 为什么要关心我们是否弹出最后一个元素?
    • @h2ooooooo 你是对的,我不敢相信我错过了。谢谢。赞成。
    【解决方案7】:

    我很惊讶没有人指出这些答案中的大多数对于数组中的零个或一个元素都不能正常工作。这是一个适用于 0+ 元素的简单解决方案:

    function prettyJoin(array) {
        return array.length > 1
               ? array.slice(0, -1).join(", ") + " and " + array.slice(-1)
               : array + "";
    }
    
    prettyJoin([]);                          // ""
    prettyJoin("one".split(" "));            // "one"
    prettyJoin("one two".split(" "));        // "one and two"
    prettyJoin("one two three".split(" "));  // "one, two and three"
    

    【讨论】:

    • 为什么不首先检查数组是否少于两个元素?
    • 你也可以这样做,例如返回数组 + "";在这种情况下。这真的只是口味问题。
    • 不,这是一个可读性和性能问题:如果您事先知道结果,就不必进行这些切片和连接。
    • 性能方面,它真的不应该很重要,因为切片/连接调用基本上什么都不做。不过,关于可读性的观点 - 我已经更新了答案。
    猜你喜欢
    • 2020-07-13
    • 1970-01-01
    • 2021-10-16
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-29
    • 2011-03-27
    相关资源
    最近更新 更多