Как преобразовать ArrayList в массив структуры?

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

var testData = "FirstName,LastName,dob,phone"+"\n"+
"John,Smith,10/01/1998,21234123"+"\n"+
"Millie,Henderson,23/03/2000,21768345"+"\n"+
"Briana,Wright,23/03/1976,22321467"+"\n";

function csvToJson(data, customOptions) {
  
  // Default options. Override with passed in parameters
  var options = {
    hasHeaderRow: true,
    fieldDelimiter: ",",
    rowDelimiter: "\n"
  };
  if (typeof customOptions === 'object' && customOptions !== null) {
    for (var option in customOptions) {
      if (options.hasOwnProperty(option)) {
        options[option] = customOptions[option];
      }
    }
  }
  
  // Break into rows
  var rows = data.split(options.rowDelimiter);
  if (rows instanceof Array !== true || rows.length == 0) {
    console.log("No rows found or invalid row delimiter.");
    return;
  }
  
  // Determine field count
  var fieldCount = parseInt(rows[0].split(options.fieldDelimiter).length);
  
  // Parse header
  if (options.hasHeaderRow == true) {
    var headerRow = rows.shift();
  } else {
    var headerRowPlaceholders = [];
    for (var i = 1; i < fieldCount + 1; i++) {
      headerRowPlaceholders.push('field'+i);
    }
    var headerRow = headerRowPlaceholders.join(options.fieldDelimiter);
  }
  headerRow = headerRow.split(options.fieldDelimiter);
  
  // Convert rows to objects
  for (var rowIndex = 0; rowIndex < rows.length; rowIndex++) {
    var rowObject = {};
    var rowData = rows[rowIndex].split(options.fieldDelimiter);
    if (rowData.length === fieldCount) {
      for (var headerIndex = 0; headerIndex < headerRow.length; headerIndex++) {
        rowObject[headerRow[headerIndex]] = rowData[headerIndex];
      }
      rows[rowIndex] = rowObject;
    } else {
      rows.splice(rowIndex, 1);
    }
  }
  
  return rows;
}

var result = csvToJson(testData, {
  hasHeaderRow: true,
  fieldDelimiter: ",",
  rowDelimiter: "\n"
});

console.log(result);

5
задан Vincent 9 October 2008 в 17:05
поделиться

6 ответов

Я предполагаю, что, так как Вы используете ArrayList, Вы используете 1.1?

В этом случае я подозреваю, что следующее работало бы:

ArrayList list = new ArrayList();
MyStruct[] array = new MyStruct[list.Count];
list.CopyTo(array); 

(редактирование - использование ToArray счета более удобно - я не знал о том, но затем, я очень редко [если когда-нибудь] используют ArrayList),

Однако, если MyStruct действительно является структурой, то я не могу сказать достаточно сильно, что изменяемые структуры являются плохой идеей - т.е. где можно установить.Name и.Content после создания. Структуры должны почти всегда быть неизменными. В действительности Ваш MyStruct похож на него, должен быть класс. Также - я не нахожусь на VB, но являюсь ими общедоступные поля? Снова - не рекомендуемый - свойства были бы предпочтительны. Я не знаю о VB, но C# 3.0 имеет некоторый очень краткий синтаксис для этого:

public class SomeType
{
    public string Name {get;set;}
    public string Content {get;set;}
}

Если Вы используете 2.0 или выше, рассматриваете Список <T> вместо ArrayList.

1
ответ дан 14 December 2019 в 13:51
поделиться

Необходимо бросить результат ToArray

MyStruct[] structs = (MyStruct[]) alList.ToArray(typeof(MyStruct));
4
ответ дан 14 December 2019 в 13:51
поделиться

ToArray является правильным способом пойти. В C# это было бы:

MyStruct[] array = (MyStruct[]) alList.ToArray(typeof(MyStruct));

Застревают Вы использующий 1.1, btw? Если Вы используете 2.0, можно ли сместиться для Списка <T> вместо этого?

1
ответ дан 14 December 2019 в 13:51
поделиться

При выполнении Visual Studio 2008, можно использовать Объект списка.

  Dim alList As New List(Of MyStruct)
  alList.Add(oStruct)
0
ответ дан 14 December 2019 в 13:51
поделиться

Это работало на меня

Dim array As MyStruct() = alList.ToArray(GetType(MyStruct))
0
ответ дан 14 December 2019 в 13:51
поделиться

В случае, если Вы используете 2.0 или позже, Вы могли бы хотеть определить свой arraylist как это:

Dim alList as New List(Of MyStruct)()
alList.Add(oStruct)

Это даст Вам ту же семантику как массив (поиск индексом, строгий контроль типов, поддержка IEnumerable, и т.д.).

Существует только две причины в.Net 2.0 и позже использовать массив вместо универсального списка:

  1. Вы знаете с абсолютной уверенностью количество объектов, которые Вы имеете и знаете, что количество не изменится. Это удивительно редко.
  2. Необходимо вызвать функцию, которая требует массива. Существует все еще достаточное количество их скрывающихся в BCL, но Ваш собственный код должен просить IEnumerable<T>, IList<T>, or ICollection<T>, и только редко массив.

Наконец, это довольно придирчиво в отношении гниды, но существует две стилистических точки, к которым я хочу обратиться в коде, который Вы отправили. Во-первых, отметьте сокращенный синтаксис, который я раньше создавал New List<MyStruct>. Существует не = символ, и Вы не должны вводить имя типа дважды. Это было поддержкой назад в 1,1 также, таким образом, нет никакого оправдания там. Во-вторых, инструкции по стилю для .NET, опубликованного Microsoft на MSDN (см. общий раздел соглашений о присвоении имен) конкретно, рекомендуют против венгерских бородавок как 'o' или 'a'. Это было хорошо для VB6/VBScript, которые были свободно введены, но .NET со строгим контролем типов, делая бородавки, ну, в общем, ужасными бородавкой.

0
ответ дан 14 December 2019 в 13:51
поделиться