为了账号安全,请及时绑定邮箱和手机立即绑定

如何展平一组数组?

如何展平一组数组?

C#
心有法竹 2022-06-12 14:31:17
我有一个由以下元素组成的数组:var schools = new [] {    new object[]{ new[]{ "1","2" }, "3","4" },    new object[]{ new[]{ "5","6" }, "7","8" },    new object[]{ new[]{ "9","10","11" }, "12","13" }};我试图展平的真正对象是将数据从 CSV 导入数组数组,然后将其加入字段值:    var q =        from c in list        join p in vocatives on c.Line[name1].ToUpper() equals p.first_name.ToUpper() into ps        from p in ps.DefaultIfEmpty()        select new object[] { c.Line,  p == null ? "(No vocative)" : p.vocative, p == null ? "(No sex)" : p.sex }; 我想展平该字符串数组以获得:string[] {    new string[]{ "1","2","3","4" },    new string[]{ "5","6","7","8" },    new string[]{ "9","10","11","12","13" }}我已经有一个可以循环执行此操作的解决方案,它在性能方面并不那么明智,但它似乎工作正常。我尝试使用SelectMany但无法提出解决方案。非常感谢您的反馈;)我尝试过 npo 的回答:var result = schools.Select(z => z.SelectMany(y=> y.GetType().IsArray            ? (object[])y : new object[] { y }));但是 CSVwriter 类方法只接受显式类型:IEnumerable<string[]>那么如何在linq中做到这一点,我试图:List<string[]> listOflists = (List<string[]>)result;InvalidCastException但不幸的是,没有去,出现了。
查看完整描述

3 回答

?
收到一只叮咚

TA贡献1821条经验 获得超5个赞

第一步,您必须将数据标准化为一种类型。然后你可以随意迭代它们。因此,首先创建一个方法来将特定点的值展平到任意深度:


public static class Extensions

{

    public static IEnumerable<object> FlattenArrays(this IEnumerable source)

    {

        foreach (var item in source)

        {

            if (item is IEnumerable inner

                && !(item is string))

            {

                foreach (var innerItem in inner.FlattenArrays())

                {

                    yield return innerItem;

                }

            }


            yield return item;

        }

    }

}

现在您可以在顶层进行迭代以获得所有值的单个数组:


// Produces one array => ["1", "2", "3", "4", ...]

var allFlat = schools.FlattenArrays().OfType<string>().ToArray();

或者您可以创建更深一层的单个数组:


foreach (var item in schools)

{

    // Produces an array for each top level e.g. ["5", "6", "7", "8"]

    var flat = item.FlattenArrays().OfType<string>().ToArray();

}


查看完整回答
反对 回复 2022-06-12
?
慕神8447489

TA贡献1780条经验 获得超1个赞

根据评论,由于您的内部数组混合了 and 的元素string[],string因此直接在 Linq 中执行此操作可能并非易事。


但是,在辅助函数(我称为Flattener)的帮助下,您可以手动对两种内部类型的处理进行分支,以返回数组中的元素(如果是string[]),或者将单个元素作为可枚举返回,如果不是。SelectMany然后可用于展平内部级别,但您似乎希望保持外级别不展平:


IE


var schools = new [] {

    new object[]{new[]{"1","2"}, "3","4"}, 

    new object[]{new[]{"5","6"}, "7","8"},

    new object[]{new[]{"9","10","11"}, "12","13"}

};


var result = schools

    .Select(s => s.SelectMany(o => Flattener(o)));

它返回一种类型IEnumerable<IEnumerable<string>>


凌乱的拆包位由以下人员完成:


public IEnumerable<string> Flattener(object o)

{

    if (o is IEnumerable<string> strings)

    {

        return strings;

    }

    if (o is string s)

    {

       return new[]{s};

    }

    return new[]{"?"};

}

请注意,上面使用了 C#7 的模式匹配功能。


结果截图由 LinqPad 提供:

//img1.sycdn.imooc.com//62a5885d0001fe5903310366.jpg

查看完整回答
反对 回复 2022-06-12
?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

如果你想通过 linq 来做,这里有一个示例


     var schools = new[] {

    new object[]{new[]{"1","2"}, "3","4"},

    new object[]{new[]{"5","6"}, "7","8"},

    new object[]{new[]{"9","10","11"}, "12","13"}

};


var result = schools.Select(z => z.SelectMany(y=> y.GetType().IsArray ? (object[])y : new object[] { y }));



查看完整回答
反对 回复 2022-06-12
  • 3 回答
  • 0 关注
  • 207 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号