在列表中创建重复项

时间:2013-08-06 12:22:59

标签: c# linq

我有以下代码来复制列表X次的成员。

虽然它起作用但感觉不是特别干净。

实时代码示例:http://rextester.com/UIVZVX7918

public static List<ServiceEndPoint> GetServiceEndPoints()
{
    const string source = "http://webSiteA.asmx,http://webSiteB.asmx";
    const int instances = 3;

    var splitEndPoints =  source.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
                                    .Select((s, i) => new ServiceEndPoint
                                                                {
                                                                    Index = i,
                                                                    Uri = s
                                                                })
                                                                .ToList();

    // Duplicate the contents of splitEndPoints "instances" number of times
    var serviceEndPoints = new List<ServiceEndPoint>();
    foreach (var point in splitEndPoints)
    {
        for (var i = 0; i < instances; i++)
        {
            serviceEndPoints.Add(point);
        }
    }

    return serviceEndPoints;
}

public class ServiceEndPoint
{
    public int Index { get; set; }
    public string Uri { get; set; }
}

有更好的方法吗?

3 个答案:

答案 0 :(得分:14)

也许有些事情如下:

var serviceEndPoints = splitEndPoints.SelectMany(t =>
    Enumerable.Repeat(t, instances)).ToList();

那会给你“A,A,A,B,B,B,C,C,C”。如果你想要“A,B,C,A,B,C,A,B,C”:

var serviceEndPoints = Enumerable.Repeat(
    splitEndPoints, instances).SelectMany(t => t).ToList();

答案 1 :(得分:8)

你可以用一点Linq来做到这一点:

int instances = 3;
var serviceEndPoints = 
    (from e in Enumerable.Range(0, instances)
     from x in serviceEndPoints
     select x)
    .ToList();

或者如果您更喜欢流利的语法:

var serviceEndPoints = Enumerable
    .Range(0, instances)
    .SelectMany(e => serviceEndPoints)
    .ToList();

请注意,给定{ A, B, C }之类的列表会生成类似{ A, B, C, A, B, C, A, B, C }的列表。如果要生成{ A, A, A, B, B, B, C, C, C }之类的列表,可以简单地颠倒集合的顺序:

var serviceEndPoints = 
    (from x in serviceEndPoints
     from e in Enumerable.Range(0, instances)
     select x)
    .ToList();

或者用流利的语法:

var serviceEndPoints = serviceEndPoints
    .SelectMany(x => Enumerable.Range(0, instances), (x, e) => x)
    .ToList();

答案 2 :(得分:1)

拆分两个组件......

var parts = source.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);

var serviceEndPoints = (from i in Enumerable.Range(0, instances * parts.Length)
                        let j = i / instances
                        let part = parts[j]
                        select new ServiceEndPoint { Index = j, Uri = part }).ToList();

...或

var parts = source.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);

var serviceEndPoints2 = (from i in Enumerable.Range(0, parts.Length)
                        let part = parts[i]
                        from j in Enumerable.Range(0, instances)                            
                        select new ServiceEndPoint { Index = i, Uri = part }).ToList();

它与另一个for非常相似: - )