Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 交错到多维数组_C#_Linq - Fatal编程技术网

C# 交错到多维数组

C# 交错到多维数组,c#,linq,C#,Linq,我和一位同事目前正在进行一系列编码挑战 然而,我们喜欢让事情稍微有趣一点,把答案记下来(是的,我知道,C#不是最好的高尔夫语言) 我们最近的一个涉及旋转立方体(int[,])。所以最后我们打了个赌,如果我能在一条线上得到这个,他会给我买午餐,反之亦然 在我母亲不愿听我说的许多退步和话之后,我终于明白了,至少我是这么想的 最后我得到了int[] 就我所见,没有简单的方法将其转换为int[,]。 所以我想问的是,在一条线内是否真的有可能 编辑1 我会发布我的源代码,但是我的同事可能会找到它,我可能会

我和一位同事目前正在进行一系列编码挑战

然而,我们喜欢让事情稍微有趣一点,把答案记下来(是的,我知道,C#不是最好的高尔夫语言)

我们最近的一个涉及旋转立方体(int[,])。所以最后我们打了个赌,如果我能在一条线上得到这个,他会给我买午餐,反之亦然

在我母亲不愿听我说的许多退步和话之后,我终于明白了,至少我是这么想的

最后我得到了int[]

就我所见,没有简单的方法将其转换为int[,]。 所以我想问的是,在一条线内是否真的有可能

编辑1


我会发布我的源代码,但是我的同事可能会找到它,我可能会失去一顿免费午餐。

如果允许您使用
Func
和lambda,您当然可以这样做,并对调用它的对象进行通用扩展

/// <typeparam name="T">Output type</typeparam>
/// <typeparam name="U">Calling type</typeparam>
/// <param name="obj">object to pipe</param>
/// <param name="func">blackbox function</param>
/// <returns>whatever</returns>
public static T ForThis<T,U> (this U obj, Func<U,T> func)
{
    return func(obj);
}
///输出类型
///呼叫类型
///对象到管道
///黑盒函数
///随便
此项的公共静态T(此U对象,Func Func)
{
返回函数(obj);
}
有了它,您应该能够通过执行以下操作将int[,]转换为int[]:

int[][] output = input.ForThis<int[][], int[,]>((obj) =>
{
    // transform obj == input of type int[,] into int[][]
    throw new NotImplementedException();
});
int[][]输出=input.ForThis((obj)=>
{
//将obj==int[,]类型的输入转换为int[][]
抛出新的NotImplementedException();
});

尽管我承认这个解决方案感觉像是作弊,因为你只是把多行转换包装成一个lambda。

你至少需要两行,一行用于声明结果数组,另一行用于实际复制数据

您可以首先将数组的数组展平为单个数组,然后使用此命令将所有数据复制到结果数组

下面是一个例子:

var source = new int[][] {
    new int[4]{1,2,3,4},
    new int[4]{5,6,7,8},
    new int[4]{1,3,2,1},
    new int[4]{5,4,3,2}
};

var expected = new int[4,4] {
    {1,2,3,4},
    {5,6,7,8},
    {1,3,2,1},
    {5,4,3,2}
};

var result = new int[4, 4];
// count = source.Length * source[0].Length * sizeof(int) = 64, since BlockCopy is byte based
// to be dynamically you could also use System.Runtime.InteropServices.Marshal.SizeOf(source[0][0]) instead of sizeof(int)
Buffer.BlockCopy(source.SelectMany(r => r).ToArray(), 0, result, 0, 64);

result.Dump("result");
expected.Dump("expected");
结果:

如果你坚持要花哨:你可以用一个委托动态调用
BlockCopy
,让该委托返回
Object
,这样你就可以用它来分配一个匿名类,这显然符合你规则的精神,并将所有内容包装到一个集合中,这样你就可以以这样一个单行怪物结束:

var result = new[]{ new int[4, 4] }.Select(x => new { r = x, tmp = Delegate.CreateDelegate(typeof(Action<Array, int, Array, int, int>), typeof(Buffer).GetMethod("BlockCopy")).DynamicInvoke(new Object[]{source.SelectMany(r => r).ToArray(), 0, x, 0, 64})}).First().r;
var result=new[]{new int[4,4]}.Select(x=>new{r=x,tmp=Delegate.CreateDelegate(typeof(Action),typeof(Buffer.GetMethod(“BlockCopy”)).DynamicInvoke(新对象[]{source.SelectMany(r=>r.ToArray(),0,x,0,64}).First().r;

您应该尝试学习javascript(我使用的是库中非常常见的模式)

这里我使用的是
Aggregate()
方法。
TSeed
是目标多维数组。注意
(md[x.i,x.y]=x.val)==x.val?md:null
:我需要分配
md[x.I,x.y]=x.val
,但我需要返回
md
(因为
Aggregate
要求函数以这种方式工作)。我做了一个无用的检查
(md[x.I,x.y]=x.val)=x.val
,并使用三元运算符返回
md


请注意,我正在关闭一个变量(
jagged
),但是可以删除该闭包(我认为)。。。。嗯,似乎很复杂。

是的,我们看了这个,双方都同意这是一种欺骗。但谢谢你的回答。从技术上讲,我可以通过在每行末尾按delete键,将任何C#程序变成一行。试图学习JS,但没有抓住我。@Darkstrycs是的。。。但这仍然是一个单一的赋值语句。。。这不是玩文字游戏。这段代码与执行
var enu=coll.Select(y=>{return y;})
之间没有什么有意义的区别。公平地说,让我用它来代替linq。@darkstyrics这里的问题是,您是根据线定义赌注的。。。你应该用状态来定义赌注。这很公平,但我们喜欢给自己制造麻烦。最糟糕的情况是我失去了一顿午餐,但我学到了一些新东西。打破了标准问题的单调,真正迫使我们探索语言的能力。
int[][] jagged = new[] { new[] { 1, 2, 3, 4, 5 }, new[] { 6, 7, 8, 9, 10 } };

int[,] array = ((Func<int[][], int[,]>)(x =>
{
    int[,] temp = new int[x.Length, x.Length != 0 ? x[0].Length : 0];
    for (int i = 0; i < x.Length; i++)
    {
        for (int j = 0; j < x[0].Length; j++)
        {
            temp[i, j] = x[i][j];
        }
    }

    return temp;
}))(jagged);
int[,] array = jagged.Length == 0 ? 
    new int[0,0] : 
    jagged.SelectMany(x => x)
        .Select((x, ix) => new
        {
            i = ix / jagged[0].Length,
            y = ix % jagged[0].Length,
            val = x
        })
        .Aggregate(new int[jagged.Length, jagged[0].Length], (md, x) => (md[x.i, x.y] = x.val) == x.val ? md : null);