zoukankan      html  css  js  c++  java
  • 2019-10-9-dotnet-不申请额外数组空间合并多个只读数组列表

    title author date CreateTime categories
    dotnet 不申请额外数组空间合并多个只读数组列表
    lindexi
    2019-10-09 15:15:10 +0800
    2019-10-9 15:8:43 +0800
    dotnet

    我在写一个简单的功能,需要将两个不同的数组合并到一起,但是我的功能只是做只读,如果合并的方法需要申请额外的内存空间,将降低性能。本文写了一个简单的方法,通过判断下标的方法做遍历多个数组组合在一起,通过判断当前获取的下标在对应哪个数组下标范围内,返回对应数组的元素

    合并多个数组或列表有多个不同的方法,但是我找到的方法都需要额外申请内存空间,需要做一次数组元素复制,相对性能比较差,如果是做只读,功能和 Span 相反,那么可以通过遍历的数组下标判断

    下面方法可以在项目用,做法很简单,看代码也就知道

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    
        public class CombineReadonlyList<T> : IReadOnlyList<T>
        {
            public CombineReadonlyList(params IReadOnlyList<T>[] source)
            {
                Source = source;
            }
    
            public IReadOnlyList<T>[] Source { get; }
    
            public IEnumerator<T> GetEnumerator()
            {
                return Source.SelectMany(readOnlyList => readOnlyList).GetEnumerator();
            }
    
            IEnumerator IEnumerable.GetEnumerator()
            {
                return GetEnumerator();
            }
    
            public int Count => Source.Sum(temp => temp.Count);
    
            public T this[int index]
            {
                get
                {
                    var n = index;
                    var source = Source;
    
                    foreach (var list in source)
                    {
                        if (n < list.Count)
                        {
                            return list[n];
                        }
    
                        n -= list.Count;
                    }
    
                    throw new IndexOutOfRangeException();
                }
            }
        }

    这个类如果不算传入的只读列表的原列表的更改,这个类是线程安全的

    可能遇到的坑是传入的只读列表的原列表添加了值,也就是 CombineReadonlyList[n] 执行两遍获取的元素可能不相同

    更多有趣的数组定义请看 Sakuno.Base.Collections github

    如果不需要获取指定下标,那么可以使用 ReadOnlyCollection 请看代码

        public class CombineReadonlyCollection<T> : IReadOnlyCollection<T>
        {
            public CombineReadonlyCollection(params IReadOnlyCollection<T>[] source)
            {
                Source = source;
            }
    
            public IReadOnlyCollection<T>[] Source { get; }
    
            public IEnumerator<T> GetEnumerator()
            {
                return Source.SelectMany(readOnlyList => readOnlyList).GetEnumerator();
            }
    
            IEnumerator IEnumerable.GetEnumerator()
            {
                return GetEnumerator();
            }
    
            public int Count => Source.Sum(temp => temp.Count);
        }
  • 相关阅读:
    docker/qemu中是如何对设备管理的
    capacilitys docker中的权限设置 privileged
    比特币的价值
    js连接sqlserver进行查询
    easyUI 添加排序到datagrid
    jquery easyui datagrid 分页 详解
    ASP.net中DateTime获取当前系统时间的大全
    计算数据库中30天以内,30-60天,60-90天,90天以外的数据的个数(用sql实现)
    常用的.net开源项目
    数据库设计三大范式
  • 原文地址:https://www.cnblogs.com/lindexi/p/12085686.html
Copyright © 2011-2022 走看看