Самый эффективный способ добавить массивы в C#?

вы можете добавить файлы gpx в свой проект и использовать его: изменить схему> параметры> разрешить моделирование местоположения> выбрать имя файла, которое содержит, например:

<?xml version="1.0"?>
<gpx version="1.1" creator="Xcode"> 
    <wpt lat="41.92296" lon="-87.63892"></wpt>
</gpx>

опционально просто hardcode lat / lon значения, возвращаемые менеджером местоположений. Это старый стиль.

, поэтому вы не добавите его в симулятор, а в свой проект Xcode.

63
задан Constantin 21 November 2008 в 14:21
поделиться

7 ответов

Вы не можете добавить к фактическому массиву - размер массива фиксируется во время создания. Вместо этого используйте List<T>, который может вырасти, поскольку это должно.

, С другой стороны, сохраняют список массивов и связывают их всех только, когда Вы захватили все.

Видят сообщение в блоге Eric Lippert на массивах для большего количества детали и понимания, чем я мог реалистично обеспечить:)

77
ответ дан Jon Skeet 7 November 2019 в 12:28
поделиться

Если можно сделать приближение количества объектов, которые будут там в конце, использовать перегрузку Списка constuctor, который берет количество в качестве параметра. Вы сохраните некоторые дорогие дублирования Списка. Иначе необходимо заплатить за него.

4
ответ дан Olmo 7 November 2019 в 12:28
поделиться

Вот применимый класс на основе того, что сказал Constantin:

class Program
{
    static void Main(string[] args)
    {
        FastConcat<int> i = new FastConcat<int>();
        i.Add(new int[] { 0, 1, 2, 3, 4 });
        Console.WriteLine(i[0]);
        i.Add(new int[] { 5, 6, 7, 8, 9 });
        Console.WriteLine(i[4]);

        Console.WriteLine("Enumerator:");
        foreach (int val in i)
            Console.WriteLine(val);

        Console.ReadLine();
    }
}

class FastConcat<T> : IEnumerable<T>
{
    LinkedList<T[]> _items = new LinkedList<T[]>();
    int _count;

    public int Count
    {
        get
        {
            return _count;
        }
    }

    public void Add(T[] items)
    {
        if (items == null)
            return;
        if (items.Length == 0)
            return;

        _items.AddLast(items);
        _count += items.Length;
    }

    private T[] GetItemIndex(int realIndex, out int offset)
    {
        offset = 0; // Offset that needs to be applied to realIndex.
        int currentStart = 0; // Current index start.

        foreach (T[] items in _items)
        {
            currentStart += items.Length;
            if (currentStart > realIndex)
                return items;
            offset = currentStart;
        }
        return null;
    }

    public T this[int index]
    {
        get
        {
            int offset;
            T[] i = GetItemIndex(index, out offset);
            return i[index - offset];
        }
        set
        {
            int offset;
            T[] i = GetItemIndex(index, out offset);
            i[index - offset] = value;
        }
    }

    #region IEnumerable<T> Members

    public IEnumerator<T> GetEnumerator()
    {
        foreach (T[] items in _items)
            foreach (T item in items)
                yield return item;
    }

    #endregion

    #region IEnumerable Members

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    #endregion
}
2
ответ дан Jonathan C Dickinson 7 November 2019 в 12:28
поделиться

Вы, возможно, не должны были бы связывать конечный результат в непрерывный массив. Вместо этого продолжайте добавлять к списку, как предложил Jon. В конце Вы будете иметь зубчатый массив (хорошо, почти прямоугольный на самом деле). Когда необходимо будет получить доступ к элементу индексом, используйте следующую схему индексации:

double x = list[i / sampleSize][i % sampleSize];

Повторение по зубчатому массиву также просто:

for (int iRow = 0; iRow < list.Length; ++iRow) {
  double[] row = list[iRow];
  for (int iCol = 0; iCol < row.Length; ++iCol) {
    double x = row[iCol];
  }
}

Это сохраняет Вас выделение памяти и копирование за счет немного более медленного доступа элемента. Будет ли это сетевым увеличением производительности, зависит от размера Ваших данных, шаблонов доступа к данным и ограничений памяти.

4
ответ дан Constantin 7 November 2019 в 12:28
поделиться

Предложение Olmo очень хорошо, но я добавил бы это: Если Вы не уверены в размере, лучше сделать его немного больше, чем немного меньший. Когда список полон, имейте в виду, что он удвоит свой размер для добавления большего количества элементов.

, Например: предположите необходимость приблизительно в 50 элементах. Если Вы будете использовать 50 размеров элементов, и заключительное число элементов равняется 51, Вы закончите 100 измеренными списками с 49 потраченными впустую положениями.

0
ответ дан rgargente 7 November 2019 в 12:28
поделиться

Решение выглядит вроде весело, но можно объединить массивы всего двумя операторами. Когда вы работаете с большими байтовыми массивами, я полагаю, неэффективно использовать связанный список для хранения каждого байта.

Вот пример кода для чтения байтов из потока и расширения байтового массива на лету:

    byte[] buf = new byte[8192];
    byte[] result = new byte[0];
    int count = 0;
    do
    {
        count = resStream.Read(buf, 0, buf.Length);
        if (count != 0)
        {
            Array.Resize(ref result, result.Length + count);
            Array.Copy(buf, 0, result, result.Length - count, count);
        }
    }
    while (count > 0); // any more data to read?
    resStream.Close();
7
ответ дан 24 November 2019 в 16:08
поделиться

Я считаю, что если у вас есть 2 массива одного типа, которые вы хотите объединить в третий массив, то есть очень простой способ сделать это.

вот код:

String[] theHTMLFiles = Directory.GetFiles(basePath, "*.html");
String[] thexmlFiles = Directory.GetFiles(basePath, "*.xml");
List<String> finalList = new List<String>(theHTMLFiles.Concat<string>(thexmlFiles));
String[] finalArray = finalList.ToArray();
28
ответ дан 24 November 2019 в 16:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: