C#通用列表将值设置为项目索引

时间:2019-05-01 14:38:55

标签: c# list linq

我有以下课程

public class DataStore
{
   public int index {get;set;}
   public string value {get;set;}
}

然后我有一个这样的列表:

var dataStoreList = new List<DataStore> 
{ 
    //Initialise with lots of objects 
}

我现在想用列表中的项目索引填充index值。

我知道我可以使用for循环,但是我可以使用一个内衬吗?也许linq有功能吗?我用谷歌搜索了几个词,但还没有找到任何有用的东西

3 个答案:

答案 0 :(得分:1)

您可以使用Select。它有一个提供索引值的重载。

var values = new string[] { "foo", "bar", "baz" };

var dataStoreList = values.Select((v, i) => new DataStore { index = i, value = v }).ToList();

答案 1 :(得分:1)

我要稍微梳头。听起来您想要的是一个项目列表,其中索引表示项目在列表中的位置。第一项为0,第二项为1,依此类推。此要求非常重要,因此您正在为其编写代码。

但是结果是List<DataStore>。如果列表的内容被修改会怎样?项目可以添加到末尾,插入到中间或删除。添加的项目可能具有错误的索引或没有索引。或者,您可以随时更改项目的索引。

此外,如果同一对象在多个列表中,该怎么办?它的索引在一个列表或另一个列表中可能是错误的。

结果是没有任何东西可以增强索引的正确性。有哪些解决方法?

潜在的问题是单个项目不“知道”它是否包含在列表中,或者它在列表中的位置是什么。列表本身更容易了解列表中项目的索引。

一种可能性是

var positionOfItemInList = myList.IndexOf(item);

列表已经知道每个项目在其中的位置。以上内容将始终指示项目在列表中的位置。

另一种选择是将Index属性设置为只读,在创建项目时将其设置,然后将该列表封装在另一个类中,以便仅将其公开为只读集合。至少以这种方式,您可以确保索引相对于一个列表是准确的。 (您仍然可以将列表中的项目添加到另一个列表中,然后索引将变得毫无意义。)

但是,要点是,对于一个项目来说,保持其自己的索引会带来索引错误或毫无意义的风险。

另外,有人孤立地看课可能会想知道Index是什么。尚不清楚,因为从技术上讲Index在类本身的上下文中没有任何意义。


添加一些评论,以阐明其意图。这是查看基本需求的完全不同的方式。

有时,当我们需要在Excel中对项目进行排序时,我们可能会先添加一个额外的列,并用数字序列填充它,以便我们可以将其重新排序为原始顺序。这类似于添加index属性时所做的事情。

但是,当我们处理引用类型时,这通常是不必要的。这是一个示例:

假设此对象表示测试结果,并且您不想更改就以某种顺序列出了它们:

public class TestResult
{
    public DateTime Completed { get; }
    public TimeSpan Duration { get; }
    public decimal Score { get; set; }
}

大多数时候,我们不需要在对象上额外的属性来告诉我们它的顺序。这可能不是一个好属性,因为它实际上并没有描述测试分数。它只是描述对象在某些集合中的位置,并且该属性可能正确也可能不正确。

如果我们有该列表,并且希望根据某些特定顺序对其进行操作,该怎么办?不必对它进行排序和排序,只需创建一个包含相同项目的新列表即可。

public void DoStuffWithListOfTestScores(List<TestResult> testResults)
{
    // testResults is in some specific order and we don't want to change it.

    AddBonusForFinishingFaster(testResults);

    // the order of testResults hasn't changed.
}

private void AddBonusForFinishingFaster(IEnumerable<TestResult> testResults)
{
    var fastestTen = testResults.OrderBy(result => result.Duration).Take(10);
    foreach (var result in fastestTen)
    {
        result.Score += 10;
    }
}

我们还没有解决如何为每个项目添加索引的问题。我们已经使问题消失了,并避免添加我们可能不需要的属性。

答案 2 :(得分:0)

我认为您正在寻找Enumerable.Range

var list = Enumerable
    .Range(0, 10)
    .Select(q => new DataStore { index = q })
    .ToList();

它将创建一个包含10个条目的列表。