简体   繁体   English

在不使用.Add()的情况下动态添加项目到列表<int>按索引

[英]Adding Items to List<int> By Index Dynamically without using .Add()

I was trying to add items to list without using .Add() dynamically , Please notice I cant use alternative data structures like dictionary or simple array or even a HashSet due to the nature of my project. 我试图在没有动态使用.Add()的情况下将项目添加到列表中。请注意,由于项目的性质,我无法使用替代数据结构,如字典或简单数组甚至是HashSet。 I need a workout solution to solve the below problem as it is : 我需要一个解决方案来解决以下问题,因为它是:

List<int> initA = new List<int>();
for (int i = 0; i < m; i++)
     initA[i] = i;

UPDATE : However if anyone suggests me a better datastructure to implement the following idea then I can use it as alternative : 更新:但是,如果有人建议我更好的数据结构来实现以下想法,那么我可以使用它作为替代:

I have set such that A for example : 我设置了这样的A例如:

A[0] = (1,2,3,4,5...)
A[1] = (10,20,30,40 ...)

and I need direct access such that : A[0][1]=2 , A[1][3]=40 I don't know what is the size of the inner array (the actual size of set elements) thats why I implement this set as Array of Lists and I cant use Jagged Array for the inner array since I don't know its size. 我需要直接访问:A [0] [1] = 2,A [1] [3] = 40我不知道内部数组的大小(设置元素的实际大小)是什么原因我将此集实现为列表数组,因为我不知道它的大小,所以我不能使用Jagged Array作为内部数组。 the set elements are added at the runtime. set元素在运行时添加。

Any Suggestions for solving the first Issue ? 有没有解决第一个问题的建议? or even a suggestion to replace the strategy of represent such set ? 甚至建议取代代表这样一套的策略?

Please notice that I need effecient data strcture since A will store >1M sets. 请注意,我需要有效的数据结构,因为A将存储> 1M套。

This is very easy task in C++ where you can use pointers ... in fact this my work around for the problem since its risky to use unsafe code in C# 这在C ++中是非常容易的任务,你可以使用指针......实际上这是我解决问题的方法,因为在C#中使用不安全的代码有风险

You can't. 你不能。

A list data structure only allows you to add items with the Add method (or similar methods, eg AddRange ). 列表数据结构仅允许您使用Add方法(或类似方法,例如AddRange )添加项目。 The indexer can only be used to modify an entry at a specific position. 索引器只能用于修改特定位置的条目。 It cannot be used to add entries to an initially empty list. 它不能用于将条目添加到最初为空的列表。

So, you definitely need to fill your list before you can modify an item at a specific position, eg: 因此,您必须先填写列表,然后才能修改特定位置的项目,例如:

List<int> initA = new List<int>(new int[m]);
for (int i = 0; i < m; i++)
     initA[i] = i;

Note that the first line is equivalent to adding m zeroes in a loop, so, technically, you did not avoid "adding" items. 请注意,第一行相当于在循环中添加m零,因此,从技术上讲,您没有避免“添加”项。

You can work around with Dictionary: 你可以使用Dictionary来解决:

Usage: 用法:

Vector<string> v = new Vector<string>();
v[0] = "item0";
v[10] = "item10";
string s = v[10]; //s will be "item10"

Code: 码:

class Vector<T>
    {
        Dictionary<int,T> list;

        public Vector ()
        {
           this.list = new Dictionary<int,T>();
        }

        public T this [int index]{
            get
            {
                if (list.ContainsKey(index))
                    return list[index];
                else return default(T);
            }
            set {
                if (list.ContainsKey(index))
                    list[index] = value;
                else 
                    list.Add(index,value);
            }

        } 
    }

Obviously you can't. 显然你不能。 List is concrete object with concrete behavior which cannot be simply changed. 列表是具体行为的具体对象,不能简单地改变。 A dirty workaround would be to pre-assign the list with default values: 一个肮脏的解决方法是使用默认值预分配列表:

var l = new List<int>(Enumerable.Repeat(0, numberOfValuesINeed));

or even: 甚至:

var l = new List<int?>(Enumerable.Repeat((int?)null, numberOfValuesINeed));

So you are able to figure out which values have not been assigned. 因此,您可以确定哪些值尚未分配。

A better option would be to implement your own IList (using List as the internal storage would make it pretty simple if you don't mind potential O(n) inserts). 一个更好的选择是实现自己的IList (使用List作为内部存储将使得它非常简单,如果你不介意潜在的O(n)插入)。

But this is all syntactic sugar, so I would either use the language as intended or use a different language that offers the dynamic behavior required. 但这都是语法糖,所以我要么按预期使用语言,要么使用提供所需动态行为的不同语言。 I cannot think of a none academic scenario where these constraints would apply. 我无法想到这些约束适用的无学术情景。

If the index is such important, you have to make sure that the element at that index actually exists or could be added. 如果索引非常重要,则必须确保该索引处的元素实际存在或可以添加。

List<int> initA = new List<int>();
for (int i = 0; i < m; i++)
     initA.SetValueAtIndex(i, i);


public static void SetValueAtIndex<T>(this IList<T> list, int index, T value)
{
  while (list.Count <= index + 1)
  {
    list.Add(default(T));
  }
  list[index] = value;
}

The weakness of these code is the .Add(default(T)) part. 这些代码的弱点是.Add(default(T))部分。 It adds items where the actual data isn't known. 它添加了实际数据未知的项目。 It this is not a problem in your case, don't mind. 这不是你的问题,不介意。 Another problem is that you could pass in a high number as index, which leads to a huge list. 另一个问题是你可以传入一个高数字作为索引,这会导致一个巨大的列表。 If this could be the case, you should definitively go with a dictionary. 如果是这种情况,你应该明确地使用字典。

Alternatively you can use an array when you know the number of items: 或者,当您知道项目数时,您可以使用数组:

int[] initA = new int[m];
for (int i = 0; i < m; i++)
     initA[i] = i;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM