-2

I have two listbox, which have characters like:

Listbox1     Listbox2
 Model1       Price1
 Model2       Price2
 Model3       Price3
 Model4       Price4

I want to display both lists in a listbox3, in this way:

 Listbox
Model1,Price1
Model2,Price2
Model3,Price3
Model4,Price4

I've tried to combine the list but I got the error:

System.ArgumentOutOfRangeException: 'Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index'

    ///
    ///Modelos
    ///

    public string[] _EModelsArray;
    public string[] _ModelsArray;
    public string[] _UnionArray;

    StreamReader _reader = new StreamReader(@".\MODELOS.txt"); // Abre el archivo de texto
    List<string> _info = new List<string>();
    while(!_reader.EndOfStream)
    {
        string _line = _reader.ReadLine().Trim();
        string [] _tokens = _line.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);

        ///
        /// crear el listado
        /// 
        var _Model = new List<string>();
        var _EModel = new List<string>();
        var _Union = new List<string>();
        //var _EQty = new List<string>();

        if (_tokens.Length == 2)
        {
            _Model.Add(_tokens[0]);
            _EModel.Add(_tokens[1]);
            //_EQty.Add(_tokens[2]);
        }

        //else
        //MessageBox.Show("Error!!!");


        ///
        /// Convertir en array
        ///
        _ModelsArray = _Model.ToArray();
        _EModelsArray = _EModel.ToArray();


        foreach (var item in _ModelsArray)
        {
            listBox1.Items.Add(item);
        }

        foreach (var item in _EModelsArray)
        {
            listbx2.Items.Add(item);
        }

        for (int i = 0; i <=30; i ++)
        {
            _Union[i] = _Model[i] + _EModel[i];
        }

        _UnionArray = _Union.ToArray();
        foreach (var item in _UnionArray)
        {
            listbx_union.Items.Add(item);
        }

whereas I am working for:

 Listbox3
Model1,Price1
Model2,Price2
Model3,Price3
Model4,Price4

Model and price combined into 1 line.

  • TBH, create a class to hold this data and then use it how you want... You are doubling back on this data... – Trevor Jul 15 '19 at 19:24
  • Possible duplicate of [How do I concatenate two arrays in C#?](https://stackoverflow.com/questions/1547252/how-do-i-concatenate-two-arrays-in-c) – Trevor Jul 15 '19 at 19:34

3 Answers3

2

You can leverage one of the LINQ .Select() overloads.

var listBox1 = new[] { "Model1", "Model2", "Model3", "Model4" };
var listBox2 = new[] { "Price1", "Price2", "Price3", "Price4" };

var listbox3 = listBox1.Select((value, element) => $"{value},{listBox2[element]}");

This overload is using the Func<string, int, string> lambda to not only use the enumerated item in the query but the item number as well. This allows you to use the item number as the array position for the second array.

You are potentially getting the error from your for loop declaration for (int i = 0; i <=30; i ++). You are providing a predetermined exactly 31 iterations for that loop. To alleviate this error, you will have to have >=31 elements in each of your arrays.

Matt Rowland
  • 4,575
  • 4
  • 25
  • 34
  • Could you please add input as to why the OP was getting the results they didn't want and why the error. This would help them see where they are going wrong. – Trevor Jul 15 '19 at 19:25
  • 1
    Thanks for the update, this will help the OP understand better where they fell off. – Trevor Jul 15 '19 at 19:43
0

The reason you're getting that error is that you have a hard-coded value of 30, and there are fewer than 31 items in your list, so you're attempting to access an index that doesn't exist in your loop condition:

for (int i = 0; i <= 30; i ++)  // This will fail if there are less than 31 items

One way to resolve this is to simply use the list's Count property in the loop condition:

for (int i = 0; i <= _Model.Count; i++)

However, it may make more sense to create a single class that has the properties you want to set for each line in the file, and then create a list of that class. Then you can set your ListBox items to a specific property of the class.

For example, we can create the class Model to look like:

class Model
{
    public string Name { get; set; }
    public string Price { get; set; }
    public string Both => $"{Name},{Price}";
}

Then we can create a method that reads a file and returns a list of this class based on the file contents:

public static List<Model> GetModels(string filePath)
{
    return File?
        .ReadAllLines(filePath)
        .Where(line => line.Contains(':'))
        .Select(line => line.Split(':'))
        .Select(lineParts => new Model { Name = lineParts[0], Price = lineParts[1] })
        .ToList();
}

And now we can just call this method to get a single list, and then update our listBoxes with the information from each item in the list:

foreach (var model in GetModels(@".\MODELOS.txt"))
{
    listBox1.Items.Add(model.Name);
    listbx2.Items.Add(model.Price);
    listbx_union.Items.Add(model.Both);
}
Rufus L
  • 36,127
  • 5
  • 30
  • 43
-1

Two things to change from a quick review of your original code. First do not use a literal number for creating the union list. Second, the union list does not have elements yet so you should use .Add(). Like this:

for (int i = 0; i < _Model.Length; i ++)
{
    _Union.Add(_Model[i] + "," + _EModel[i]);
}
Kevin Brock
  • 8,874
  • 1
  • 33
  • 37