Inicializovat Jagged Array LINQ Way

hlasů
9

Mám 2-rozměrné zubaté pole (i když je to vždy obdélníkový), který jsem inicializovat pomocí tradiční smyčky:

var myArr = new double[rowCount][];
for (int i = 0; i < rowCount; i++) {
    myArr[i] = new double[colCount];
}

Myslel jsem, že by mi nějaká funkce LINQ dát elegantní způsob, jak to udělat v jednom příkazu. Nicméně, nejbližší můžu přijít s je toto:

double[][] myArr = Enumerable.Repeat(new double[colCount], rowCount).ToArray();

Problém je, že se zdá, že vytvoření jednotného double[colCount]a přiřazení odkazy na tomto intsead přidělení nové pole pro každý řádek. Existuje způsob, jak to udělat, aniž by se příliš mystický?

Položena 08/07/2009 v 19:14
zdroj uživatelem
V jiných jazycích...                            


6 odpovědí

hlasů
23

double[][] myArr = Enumerable
  .Range(0, rowCount)
  .Select(i => new double[colCount])
  .ToArray();
Odpovězeno 08/07/2009 v 19:27
zdroj uživatelem

hlasů
2

Co máte nebude fungovat, protože newdojde před volání Repeat. Budete potřebovat něco, co také opakuje vytvoření pole. Toho může být dosaženo pomocí Enumerable.Rangemetody pro generování řady a pak provedením Selectoperace , která mapuje každý prvek rozsahu do nové instance pole (jako v odpovědi David B v ).

Nicméně si myslím, že se snažíte použít LINQ, kde to není opravdu vhodné tak učinit v tomto případě. Co byste měli před řešení LINQ je v pohodě. Samozřejmě, pokud jste chtěli přístup LINQ ve stylu podobný Enumerable.Repeat, můžete napsat svůj vlastní způsob rozšíření, které generuje nové položky, jako jsou:

    public static IEnumerable<TResult> Repeat<TResult>(
          Func<TResult> generator,
          int count)
    {
        for (int i = 0; i < count; i++)
        {
            yield return generator();
        }
    }

Pak můžete volat následujícím způsobem:

   var result = Repeat(()=>new double[rowCount], columnCount).ToArray();
Odpovězeno 08/07/2009 v 19:27
zdroj uživatelem

hlasů
0

Jen jsem napsal tuto funkci ...

    public static T[][] GetMatrix<T>(int m, int n)
    {
        var v = new T[m][];
        for(int i=0;i<m; ++i) v[i] = new T[n];
        return v;
    }

Zdá se, že práce.

Používání:

float[][] vertices = GetMatrix<float>(8, 3);
Odpovězeno 24/12/2011 v 03:50
zdroj uživatelem

hlasů
0

Můžete to udělat pomocí Repeatmetody: elementparametr je hodnocena pouze jednou, takže opravdu to vždy opakuje stejnou instanci. Místo toho můžete vytvořit metodu dělat to, co chcete, která by se lambda namísto hodnoty:

    public static IEnumerable<T> Sequence<T>(Func<T> generator, int count)
    {
        for (int i = 0; i < count; i++)
        {
            yield return generator();
        }
    }

    ...

    var myArr = Sequence(() => new double[colCount], rowCount).ToArray();
Odpovězeno 08/07/2009 v 19:32
zdroj uživatelem

hlasů
0

Chování je správné - Repeat()vrací sekvenci, která obsahuje Zadaný objekt vícekrát. Můžete tak učinit na následující trik.

double[][] myArr = Enumerable
    .Repeat(0, rowCount)
    .Select(i => new double[colCount])
    .ToArray();
Odpovězeno 08/07/2009 v 19:30
zdroj uživatelem

hlasů
-1

Co takhle

var myArr = new double[rowCount, colCount];

nebo

double myArr = new double[rowCount, colCount];

Reference: http://msdn.microsoft.com/en-us/library/aa691346(v=vs.71).aspx

Odpovězeno 07/10/2014 v 19:32
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more