Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge two arrays in a Key => Value

Tags:

arrays

c#

linq

I have two arrays with the same length and I need to use the first as a Key and the second as a Value.

My Key is an unique string and my Value is a double. I have 6 capybaras. Their names will be the key and their weight is the pound.

My current code:

        ViewBag.MeuBalaioDeCapivaras = new string[]
        {
            "Jerimúndia",
            "Genoveva",
            "Facibulana",
            "Carnavala",
            "Dentinhos Dourados",
            "Creusa"
        };

        ViewBag.PesoDeCadaCapivaraDoMeuBalaioDeCapivaras = new double[]
        {
            500.0,
            400.0,
            250.0,
            12.0,
            1589.0,
            87.3
        };

This is my Arrays and I was doing as a KeyValuePair:

var keyValuePair = new KeyValuePair<string, double>(ViewBag.NomeDaCapivara, ViewBag.PesoDeCadaCapivaraDoMeuBalaioDeCapivaras);

It compiles perfectly, but in the end it gives me an exception, when running:

=> An exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in System.Core.dll but was not handled in user code. Additional information: The best correspondence of the overloaded method.

How can I do what I need?

like image 906
Marcelo Camargo Avatar asked Dec 14 '22 20:12

Marcelo Camargo


2 Answers

LINQ has a little-known function to do just that - Zip. The function takes two collections and merges them into a single collection:

int[] numbers = { 1, 2, 3, 4 };
string[] words = { "one", "two", "three" };

var numbersAndWords = numbers.Zip(words, (number, word) => new KeyValuePair<string,int>(word, number);
like image 143
Avner Shahar-Kashtan Avatar answered Jan 02 '23 18:01

Avner Shahar-Kashtan


Your code compiles because ViewBag is dynamic, this means there is no compile time checking.

If you replaced

var keyValuePair = new KeyValuePair<string, double>(ViewBag.NomeDaCapivara, ViewBag.PesoDeCadaCapivaraDoMeuBalaioDeCapivaras);

If you put the arrays in directly, you would get the compile time error you are expecting: e.g.

var keyValuePair = new KeyValuePair<string, double>(
    new string[] { "Jerimúndia", "Genoveva", "Facibulana", "Carnavala", "Dentinhos Dourados", "Creusa" },
new double[] { 500.0, 400.0, 250.0, 12.0, 1589.0, 87.3 });

Gives:

Compilation error (line x1, col y1): The best overloaded method match for 'System.Collections.Generic.KeyValuePair<string,double>.KeyValuePair(string, double)' has some invalid arguments
Compilation error (line x2, col y2): Argument 1: cannot convert from 'string[]' to 'string'
Compilation error (line x3, col y3): Argument 2: cannot convert from 'double[]' to 'double'

The old school, explicit way to do this would be something like:

    var meuBalaioDeCapivaras = new string[]
    {
    "Jerimúndia", "Genoveva", "Facibulana", "Carnavala", "Dentinhos Dourados", "Creusa"
    };

    var pesoDeCadaCapivaraDoMeuBalaioDeCapivaras = new double[]
    {
    500.0, 400.0, 250.0, 12.0, 1589.0, 87.3
    };

    var list = new List<KeyValuePair<string, double>>();

    for (var i = 0; i < meuBalaioDeCapivaras.Length; i++)
    {
        list.Add(new KeyValuePair<string, double>(meuBalaioDeCapivaras[i], pesoDeCadaCapivaraDoMeuBalaioDeCapivaras[i]));
    }

As Felipe Oriani and Avner Shahar-Kashtan have stated, if you are using .NET 3.5 or above, you can use Linq

like image 35
BanksySan Avatar answered Jan 02 '23 20:01

BanksySan