一个如何连接字符串类型的数组项,每个项都有一个逗号字符,除了最后一项必须用“and”连接?

Posted

技术标签:

【中文标题】一个如何连接字符串类型的数组项,每个项都有一个逗号字符,除了最后一项必须用“and”连接?【英文标题】:How does one join string-type array-items, each with a comma character, except for the last item which has to be joined by "and"? 【发布时间】:2021-02-05 07:01:51 【问题描述】:

我有一个看起来像这样的字符串数组。

['white t-shirt', 'blue jeans', 'red hat', 'brown glasses'...]

我需要以某种方式将这些字符串用逗号放在以下文本中,但在最后一项而不是逗号之前,我需要设置 and。像这样的:

'您的卡片包括白色 T 恤、蓝色牛仔裤、红色帽子和棕色眼镜,您可以前往结帐页面'

由于我要从后端接收这些数组项,我需要以某种方式使上述字符串生成动态化。如果可能没有循环如何实现?

【问题讨论】:

如果我错了,请纠正我,但根据英语语法,AFAIK 仍然应该在“and”之前加一个逗号。 @YuryTarabanko 不,没有固定的政策,研究“牛津逗号”。 【参考方案1】:
strings = ['white t-shirt', 'blue jeans', 'red hat', 'brown glasses'];
lastString = strings.pop();
result = strings.join(', ') + ' and ' + lastString;

【讨论】:

至少改变原始数组是一种不好的做法。 很难用一些复杂的 hiperbole 来修复,例如 mmm、ourStrings = [...strings] 并使用 ourStrings。 嗯,很好,你也知道解构。这就是你所说的“高性能解决方案”?【参考方案2】:

您可以使用数组的slice 方法简单地做到这一点。

const arr = ['white t-shirt', 'blue jeans', 'red hat', 'brown glasses'];

const result = arr.slice(0, arr.length - 1).join(', ') + ' and ' + arr.slice(-1)[0];

console.log(result);

【讨论】:

Array.prototype.splice 返回一个数组。将字符串与数组混合并依赖隐式强制转换不是好的做法。【参考方案3】:

没有临时保存的引用,但原始 strings 数组发生了变异...

const strings = ['white t-shirt', 'blue jeans', 'red hat', 'brown glasses'];

console.log(
  [strings.pop(), strings.join(', ')].reverse().join(' and ')
);
console.log('mutated ... strings :', strings);
.as-console-wrapper  min-height: 100%!important; top: 0; 

没有临时保存的引用,这次没有改变原始strings 数组...

const strings = ['white t-shirt', 'blue jeans', 'red hat', 'brown glasses'];

console.log(
  [strings.slice(0, strings.length - 1).join(', '), ...strings.slice(-1)].join(' and ')
);
console.log('not mutated ... strings :', strings);
.as-console-wrapper  min-height: 100%!important; top: 0; 

【讨论】:

【参考方案4】:

Intl API 的一部分称为Intl.ListFormat。如果您想根据语言环境规则进行正确的列表格式设置,我建议您使用它而不是手动格式设置。

例如,在提供的情况下,“and”之前应该有一个逗号。

const strings = ['white t-shirt', 'blue jeans', 'red hat', 'brown glasses'];

const formatter = new Intl.ListFormat('en',  style: 'long', type: 'conjunction' );
console.log(formatter.format(strings));

const short = ['white t-shirt', 'blue jeans'];

console.log(formatter.format(short));

【讨论】:

:P grammarly.com/blog/… @malarres CLDR 认为它应该在那里 ;) 感谢您的链接和示例。我不知道那个。学到了一些东西。 最好的主意,但不能在日常实践中使用,因为 Safari 不支持此 API。 @VladislavLadicky 虽然可以使用 polyfil formatjs.io/docs/polyfills/intl-listformat【参考方案5】:

reduce的解决方案:

const arr = ['white t-shirt', 'blue jeans', 'red hat', 'brown glasses']


const showList = () => 
  const OXFORD_COMMA=document.getElementById('oxford-comma').value;
  console.log(arr.reduce((acc,item,i) => (i<arr.length-1)?acc+', '+item:acc+OXFORD_COMMA+' and '+item));
<p> Do you want to apply Oxford Comma rule? </p>
<select id="oxford-comma">
  <option value=",">Yes</option>
  <option value="">No</option>
</select>
<button type="button" onclick="showList()">output to console</button>

更新:感谢@yuri-tarabanko,现在有了“牛津逗号”选项 :)

【讨论】:

Reduce 返回一个数组。我认为这是一个不适合这项任务的方法。 “reduce() 方法在数组的每个元素上执行一个 reducer 函数(您提供的),从而产生单个输出值。” developer.mozilla.org/en-US/docs/Web/javascript/Reference/… 不错。和?使用reduce方法仍然是这里最弱的想法。【参考方案6】:

此解决方案不会改变您的原始数组,仅使用字符串方法,因此不依赖于隐式强制,并且浏览器很好地支持它。 Intl.ListFormat 是更好的主意,不幸的是,Safari 和 Edge 都不支持此 API。

let items = [
  'white t-shirt',
  'blue jeans',
  'red hat',
  'brown glasses'
]

let strings = items
  .join(', ')
  .replace(/,\s*([^,]+)$/, ' and $1')

【讨论】:

通过使用该正则表达式,您可以更改数据。包含逗号的最后一项将被修改。代码的易读性和性能也很重要。 更改数据?如何?你在说什么?您的代码可以更改数据 - 源数组,而不是我的。 如果最后一项是“brown, glass”,您将在错误的位置插入 and,将其转换为“brown and glass”,破坏数据,因为源数据中没有

以上是关于一个如何连接字符串类型的数组项,每个项都有一个逗号字符,除了最后一项必须用“and”连接?的主要内容,如果未能解决你的问题,请参考以下文章

数组的学习

List.JS - 使用逗号分隔值过滤

如何在 SwiftUI 中创建一个列表视图,每个列表项都是一个 WKWebView(我的实现非常慢并且有问题)

java数据问题

编写一个java程序,一个整数数组中的每个元素用逗号连接成一个字符串,例如,根据内容为[1][2][3]的数组形

如何将两个int类型数组连接为一个string类型数组