JavaScript数组转为句子

16

我该如何在Javascript中将一个数组,例如["Susy", "John", "Mary"]转换为"Susy, John, and Mary"?我无法摆脱Ruby的to_sentence方法。


4
不是很严肃,但是... ["Susy", "John", "Mary"].join(',').split(/,M/).join(' and M'); - jAndy
12个回答

21

使用最新的JavaScript(Chrome 72+):

new Intl.ListFormat().format(["Susy", "John", "Mary"]);

这将导致:

"Susy, John, and Mary"

2
哇,当它被支持时,这将会很棒!https://developers.google.com/web/updates/2018/12/intl-listformat - Petercopter
太棒了!但不幸的是,其他浏览器仍然支持得很差 :( https://caniuse.com/#search=ListFormat - morgler

13

将除最后一项之外的所有项目加在一起,然后再添加上最后一项:

var s = arr.slice(0, arr.length - 1).join(', ') + ", and " + arr.slice(-1);

演示: http://jsfiddle.net/JYKcK/1/


1
只是提醒一下 - 美国人在“and”之前会加上逗号。 OP 已经这样做了。 - Popnoodles
@popnoodles:啊,那么你只需要使用 + ", and " + - Guffa
9
我发现这种方法存在几个问题。如果数组里只有一个元素,它会返回“和苏茜”(英文原文中为“, and Susy”)。而对于两个元素,它会返回“苏茜,和约翰”(英文原文中为“Susy, and John”),这在语法上是不正确的。 - Alex
@Alex:是的,如果少于三个项目,您需要额外的代码,但这超出了问题的范围。这里没有答案可以处理这种情况。 - Guffa
为什么要点踩?如果你不解释哪里有问题,那么回答就无法得到改进。 - Guffa
显示剩余3条评论

11

另一种选择是使用Array.prototype.reduce,代码如下:

var arr = [1,2,3];
arr.reduce(
  function(prev, curr, i){ 
    return prev + curr + ((i===arr.length-2) ? ' and ' : ', ')
  }, '')
.slice(0, -2);

生成"1, 2 and 3"


6
toSentence = function(arr){ return arr.join(", ").replace(/,\s([^,]+)$/, ' and $1');};

toSentence(['dogs', 'cats']);           // => dogs and cats

toSentence(['dogs', 'cats', 'snakes']); // => dogs, cats and snakes

6

这里有几种特殊情况:

  1. 我们是否要在 "and" 前面加逗号 (牛津逗号)
  2. 无论如何,如果只有两个元素,我们不希望有逗号
  3. 如果只有一个元素,我们只想返回那个词

我认为这符合所有这些用例:

function joinSentence( array, oxford_comma ){
  if( array.length > 1 ){
    var lastWord = " and " + array.pop();
    if( oxford_comma && array.length > 1 ){
      lastWord = "," + lastWord;
    }
  }else{
    var lastWord = "";
  }
  return array.join(", ") + lastWord;
}

3
另外一种解决方案是:
(function(a) {
    var b = (a||(a=[])).pop(); 
    return (b ? a.length ? [a.join(", "),b] : [b] : a).join(" and ");
})(["Susy", "John", "Mary"]);

或者只需在数组的原型中定义类似 Ruby 语句的方法:

Array.prototype.sentence = function(comma,and) {
    var b = this.pop();
    return (b ? this.length ? [this.join(comma||", "),b] : [b] : this).join(and||" and ");
};

["Susy", "John", "Mary"].sentence(); 
//"Susy, John and Mary"

["Susy", "John", "Mary"].sentence(" and ", " as well as "); 
//"Susy and John as well as Mary"

["Susy", "John", "Mary", "Helmut"].sentence(); 
//"Susy, John, Mary and Helmut"

2
修改最后一个然后连接。
var source = ["Susy", "John", "Mary"];
source.push( 'and ' +source.pop());
console.log(source.join(', '))// Susy, John, and Mary

好的,这更性感了 :) 但在and之前加逗号语法上是否正确? - mika
不适用于1和2个元素:["Susy"] => "and Susy"。["Susy", "John"] => "Susy, and John"。 - Bryan Ash

2

请尝试以下操作:

var array = ['susy', 'john', 'mary'];
var last = array.pop();
var string = array.join(', ') + " and " + last;

我没有尝试过,但你应该能理解这个想法。

1
你可以使用.join()并在最后一个值前加上"and"。
var array = ['susy', 'john', 'mary'];

array[array.length-1] = 'and '+array[array.length-1];

//string is "susy, john, and mary"
var string = array.join(', ');

我知道这个方法,我想在最后一个项目之前加上“和”。 - Corey
我的错,我没有看到“and”...让我重构一下。 - joeltine

0

一个非常简单的方法:

function toSentence(array) {
  const lastWord = (array.length > 1) ? ` and ${array.pop()}` : ''
  return array.join(', ') + lastWord
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接