我知道我可以想出办法,但我想知道是否有更简洁的解决方案。始终有String.Join(", ", lList)
和lList.Aggregate((a, b) => a + ", " + b);
,但我想为最后一个添加例外,以", and "
作为其加入字符串。 Aggregate()
在我可以使用的地方有一些索引值吗?感谢。
答案 0 :(得分:18)
你可以这样做
string finalString = String.Join(", ", myList.ToArray(), 0, myList.Count - 1) + ", and " + myList.LastOrDefault();
答案 1 :(得分:11)
这是一个解决方案,它使用空列表和列表,其中包含一个项目:
return list.Count() > 1 ? string.Join(", ", list.Take(list.Count() - 1)) + " and " + list.Last() : list.FirstOrDefault();
Return If(list.Count() > 1, String.Join(", ", list.Take(list.Count() - 1)) + " and " + list.Last(), list.FirstOrDefault())
答案 2 :(得分:7)
我使用以下扩展方法(也有一些代码保护):
public static string OxbridgeAnd(this IEnumerable<String> collection)
{
var output = String.Empty;
var list = collection.ToList();
if (list.Count > 1)
{
var delimited = String.Join(", ", list.Take(list.Count - 1));
output = String.Concat(delimited, ", and ", list.LastOrDefault());
}
return output;
}
这是一个单元测试:
[TestClass]
public class GrammarTest
{
[TestMethod]
public void TestThatResultContainsAnAnd()
{
var test = new List<String> { "Manchester", "Chester", "Bolton" };
var oxbridgeAnd = test.OxbridgeAnd();
Assert.IsTrue( oxbridgeAnd.Contains(", and"));
}
}
<强> 修改 强>
此代码现在处理null和单个元素:
public static string OxbridgeAnd(this IEnumerable<string> collection)
{
var output = string.Empty;
if (collection == null) return null;
var list = collection.ToList();
if (!list.Any()) return output;
if (list.Count == 1) return list.First();
var delimited = string.Join(", ", list.Take(list.Count - 1));
output = string.Concat(delimited, ", and ", list.LastOrDefault());
return output;
}
答案 3 :(得分:5)
此版本枚举一次值并使用任意数量的值:
import csv
import pandas as pd
with open('2column.csv','rb') as f:
reader = csv.reader(f)
a = list(reader)
gene = []
ratio = []
for t in range(len(a)):
if '///' in a[t][0]:
s = a[t][0].split('///')
gene.append(s[0])
gene.append(s[1])
ratio.append(a[t][1])
ratio.append(a[t][1])
else:
gene.append(a[t][0])
ratio.append(a[t][1])
gene[t] = gene[t].strip()
newgene = []
newratio = []
for i in range(len(gene)):
g = gene[i]
r = ratio[i]
if g not in newgene:
newgene.append(g)
for j in range(i+1,len(gene)):
if g==gene[j]:
if ratio[j]>r:
r = ratio[j]
newratio.append(r)
for i in range(len(newgene)):
print newgene[i] + '\t' + newratio[i]
if len(newgene) > len(set(newgene)):
print 'missionfailed'
答案 4 :(得分:2)
此版本仅枚举一次值,并且可以使用任意数量的值。
(改进了@Grastveit answer)
我将其转换为扩展方法并添加了一些单元测试。添加了一些空检查。
此外,如果values
集合中的某个项目包含null
,并且它是最后一个项目,我会修改一个错误,它会被跳过。这与String.Join()
在.NET Framework中的行为方式不符。
#region Usings
using System;
using System.Collections.Generic;
using System.Text;
#endregion
namespace MyHelpers
{
public static class StringJoinExtensions
{
public static string JoinAnd<T>(this IEnumerable<T> values,
string separator, string lastSeparator = null)
{
if (values == null)
throw new ArgumentNullException(nameof(values));
if (separator == null)
throw new ArgumentNullException(nameof(separator));
var sb = new StringBuilder();
var enumerator = values.GetEnumerator();
if (enumerator.MoveNext())
sb.Append(enumerator.Current);
bool objectIsSet = false;
object obj = null;
if (enumerator.MoveNext())
{
obj = enumerator.Current;
objectIsSet = true;
}
while (enumerator.MoveNext())
{
sb.Append(separator);
sb.Append(obj);
obj = enumerator.Current;
objectIsSet = true;
}
if (objectIsSet)
{
sb.Append(lastSeparator ?? separator);
sb.Append(obj);
}
return sb.ToString();
}
}
}
#region Usings
using MyHelpers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
#endregion
namespace UnitTests
{
[TestClass]
public class StringJoinExtensionsFixture
{
[DataTestMethod]
[DataRow("", "", null, null)]
[DataRow("1", "1", null, null)]
[DataRow("1 and 2", "1", "2", null)]
[DataRow("1, 2 and 3", "1", "2", "3")]
[DataRow(", 2 and 3", "", "2", "3")]
public void ReturnsCorrectResults(string expectedResult,
string string1, string string2, string string3)
{
var input = new[] { string1, string2, string3 }
.Where(r => r != null);
string actualResult = input.JoinAnd(", ", " and ");
Assert.AreEqual(expectedResult, actualResult);
}
[TestMethod]
public void ThrowsIfArgumentNulls()
{
string[] values = default;
Assert.ThrowsException<ArgumentNullException>(() =>
StringJoinExtensions.JoinAnd(values, ", ", " and "));
Assert.ThrowsException<ArgumentNullException>(() =>
StringJoinExtensions.JoinAnd(new[] { "1", "2" }, null,
" and "));
}
[TestMethod]
public void LastSeparatorCanBeNull()
{
Assert.AreEqual("1, 2", new[] { "1", "2" }
.JoinAnd(", ", null),
"lastSeparator is set to null explicitly");
Assert.AreEqual("1, 2", new[] { "1", "2" }
.JoinAnd(", "),
"lastSeparator argument is not specified");
}
[TestMethod]
public void SeparatorsCanBeEmpty()
{
Assert.AreEqual("1,2", StringJoinExtensions.JoinAnd(
new[] { "1", "2" }, "", ","), "separator is empty");
Assert.AreEqual("12", StringJoinExtensions.JoinAnd(
new[] { "1", "2" }, ",", ""), "last separator is empty");
Assert.AreEqual("12", StringJoinExtensions.JoinAnd(
new[] { "1", "2" }, "", ""), "both separators are empty");
}
[TestMethod]
public void ValuesCanBeNullOrEmpty()
{
Assert.AreEqual("-2", StringJoinExtensions.JoinAnd(
new[] { "", "2" }, "+", "-"), "1st value is empty");
Assert.AreEqual("1-", StringJoinExtensions.JoinAnd(
new[] { "1", "" }, "+", "-"), "2nd value is empty");
Assert.AreEqual("1+2-", StringJoinExtensions.JoinAnd(
new[] { "1", "2", "" }, "+", "-"), "3rd value is empty");
Assert.AreEqual("-2", StringJoinExtensions.JoinAnd(
new[] { null, "2" }, "+", "-"), "1st value is null");
Assert.AreEqual("1-", StringJoinExtensions.JoinAnd(
new[] { "1", null }, "+", "-"), "2nd value is null");
Assert.AreEqual("1+2-", StringJoinExtensions.JoinAnd(
new[] { "1", "2", null }, "+", "-"), "3rd value is null");
}
}
}
答案 5 :(得分:-1)
我能想到的最简单的方法是这样... print(','。join(a [0:-1])+'和'+ a [-1])
a = [a, b, c, d]
print(', '.join(a[0:-1]) + ', and ' + a[-1])
a,b,c和d
或者,如果您不喜欢加拿大语法,牛津逗号和多余的花体字
print(', '.join(a[0:-1]) + ' and ' + a[-1])
a,b,c和d
保持简单。