Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.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#中的Datetime键获取列表的子集?_C#_Sorting_List - Fatal编程技术网

如何根据C#中的Datetime键获取列表的子集?

如何根据C#中的Datetime键获取列表的子集?,c#,sorting,list,C#,Sorting,List,我有一个元素列表,描述在某个时间发生的事件,时间被表示为对象上的Datetime属性“StartTime”。现在,我希望提取这些事件的一个子集,其中包含放置在两个DateTime实例a、B之间的间隔/中的元素,以便StartTime>=a&&StartTime如果可能,我会将实例保留在一个数组中,按StartTime排序,然后调用BinarySearch来确定数组中边界结束处的索引 然后,考虑到这一点,您可以轻松快速地访问基于日期范围的子集 我已经建立了一个通用类,它也可以帮助您: public

我有一个元素列表,描述在某个时间发生的事件,时间被表示为对象上的Datetime属性“StartTime”。现在,我希望提取这些事件的一个子集,其中包含放置在两个DateTime实例a、B之间的间隔/中的元素,以便StartTime>=a&&StartTime如果可能,我会将实例保留在一个数组中,按StartTime排序,然后调用BinarySearch来确定数组中边界结束处的索引

然后,考虑到这一点,您可以轻松快速地访问基于日期范围的子集

我已经建立了一个通用类,它也可以帮助您:

public class BinarySearcher<T>
{
    // Possibly passed to the call to BinarySort.
    private class ComparisonComparer : Comparer<T>
    {
        Comparison<T> comparison;

        internal static IComparer<T> Create(Comparison<T> comparison)
        {
            // If comparison is null, return the default comparer for T.
            if (comparison == null)
            {
                // Return the default.
                return Comparer<T>.Default;
            }

            // Return a new implementation.
            return new ComparisonComparer(comparison);
        }

        private ComparisonComparer(Comparison<T> comparison)
        {
            this.comparison = comparison;
        }

        public override int Compare(T x, T y)
        {
            return comparison(x, y);
        }
    }

    // The elements.
    T[] elements;

    // The IComparable implementation.
    IComparer<T> comparer;

    // Do not assume sorting.
    public BinarySearcher(IEnumerable<T> elements) : 
        this(elements, false, (IComparer<T>) null) { }

    // Use default comparer.
    public BinarySearcher(IEnumerable<T> elements, bool sorted) :
        this(elements, sorted, (IComparer<T>) null) { }

    // Assume no sorting.
    public BinarySearcher(IEnumerable<T> elements, 
        Comparison<T> comparer) :
            this(elements, false, 
                ComparisonComparer.Create(comparer)) { }

    // Convert to IComparable<T>.
    public BinarySearcher(IEnumerable<T> elements, bool sorted, 
        Comparison<T> comparer) :
            this(elements, sorted, 
                ComparisonComparer.Create(comparer)) { }

    // No sorting.
    public BinarySearcher(IEnumerable<T> elements, 
        IComparer<T> comparer) :
            this(elements, false, comparer) { }

    // Convert to array.
    public BinarySearcher(IEnumerable<T> elements, bool sorted, 
        IComparer<T> comparer) :
            this(elements.ToArray(), sorted, comparer) { }

    // Assume no sorting.
    public BinarySearcher(T[] elements) : this(elements, false) { }

    // Pass null for default comparer.
    public BinarySearcher(T[] elements, bool sorted) : 
        this(elements, sorted, (IComparer<T>) null) { }

    // Assume not sorted.
    public BinarySearcher(T[] elements, Comparison<T> comparer) :
        this(elements, false, ComparisonComparer.Create(comparer)) { }

    // Create IComparable<T> from Comparable<T>.
    public BinarySearcher(T[] elements, bool sorted, 
        Comparison<T> comparer) :
            this(elements, sorted, ComparisonComparer.Create(comparer)) { }

    // Assume the elements are not sorted.
    public BinarySearcher(T[] elements, IComparer<T> comparer) : 
        this(elements, false, comparer) { }

    public BinarySearcher(T[] elements, bool sorted, 
        IComparer<T> comparer)
    {
        // If the comparer is null, create the default one.
        if (comparer == null)
        {
            // Set to the default one.
            comparer = Comparer<T>.Default;
        }

        // Set the comparer.
        this.comparer = comparer;

        // Set the elements.  If they are sorted already, don't bother, 
        // otherwise, sort.
        if (!sorted)
        {
            // Sort.
            Array.Sort(elements, this.comparer);
        }

        // Set the elements.
        this.elements = elements;
    }

    public IEnumerable<T> Between(T from, T to)
    {
        // Find the index for the beginning.
        int index = Array.BinarySearch(this.elements, from, comparer);

        // Was the item found?
        bool found = (index >= 0);

        // If the item was not found, take the bitwise 
        // compliment to find out where it would be.
        if (!found)
        {
            // Take the bitwise compliment.
            index = ~index;
        }

        // If the item was found, cycle backwards from
        // the index while there are elements that are the same.
        if (found)
        {
            // Cycle backwards.
            for (; index >= 0 && 
                comparer.Compare(from, elements[index]) == 0; 
                --index) ;

            // Add one to the index, since this is on the element 
            // that didn't match the comparison.
            index++;
        }

        // Go forward now.
        for ( ; index < elements.Length; index++)
        {
            // Return while the comparison is true.
            if (comparer.Compare(elements[index], to) <= 0)
            {
                // Return the element.
                yield return elements[index];
            }
            else
            {
                // Break
                yield break;
            }
        }
    }
}
您可以执行以下操作:

// Create tasks.
Task[] tasks = 
{ 
    new Task() { Name = "Task 1", StartTime = new DateTime(2009, 02, 18) },
    new Task() { Name = "Task 2", StartTime = new DateTime(2009, 02, 16) },
    new Task() { Name = "Task 3", StartTime = new DateTime(2009, 02, 12) },
    new Task() { Name = "Task 4", StartTime = new DateTime(2009, 02, 11) },
    new Task() { Name = "Task 5", StartTime = new DateTime(2009, 02, 10) },
    new Task() { Name = "Task 6", StartTime = new DateTime(2009, 02, 01) },
    new Task() { Name = "Task 7", StartTime = new DateTime(2009, 02, 09) }
};

// Now create the indexer.
BinarySearcher<Task> searcher = new BinarySearcher<Task>(tasks,
    (x, y) => Comparer<DateTime>.Default.Compare(x.StartTime, y.StartTime));

foreach (Task t in searcher.Between(
    new Task() { StartTime = new DateTime(2009, 02, 13) },
    new Task() { StartTime = new DateTime(2009, 02, 10) }))
{
    // Write.
    Console.WriteLine(t);
}
//创建任务。
任务[]任务=
{ 
新任务(){Name=“Task 1”,StartTime=new DateTime(2009,02,18)},
新任务(){Name=“Task 2”,StartTime=new DateTime(2009,02,16)},
新任务(){Name=“Task 3”,StartTime=new DateTime(2009,02,12)},
新任务(){Name=“Task 4”,StartTime=new DateTime(2009,02,11)},
新任务(){Name=“Task 5”,StartTime=new DateTime(2009,02,10)},
新任务(){Name=“Task 6”,StartTime=new DateTime(2009,02,01)},
新任务(){Name=“Task 7”,StartTime=new DateTime(2009,02,09)}
};
//现在创建索引器。
BinarySearcher search=新的BinarySearcher(任务,
(x,y)=>Comparer.Default.Compare(x.StartTime,y.StartTime));
foreach(searcher.Between中的任务t(
新任务(){StartTime=new DateTime(2009,02,13)},
新任务(){StartTime=newdatetime(2009,02,10}))
{
//写。
控制台写入线(t);
}

是否签出数组。使用自定义谓词查找?

啊,谢谢。我不知道BinarySearch(..)在没有找到精确匹配时返回了“最近的索引”。据我所知,在SortedList上没有直接的搜索方法。只需要弄清楚是否可以直接访问SortedList的值数组,以重用插入逻辑。
// Create tasks.
Task[] tasks = 
{ 
    new Task() { Name = "Task 1", StartTime = new DateTime(2009, 02, 18) },
    new Task() { Name = "Task 2", StartTime = new DateTime(2009, 02, 16) },
    new Task() { Name = "Task 3", StartTime = new DateTime(2009, 02, 12) },
    new Task() { Name = "Task 4", StartTime = new DateTime(2009, 02, 11) },
    new Task() { Name = "Task 5", StartTime = new DateTime(2009, 02, 10) },
    new Task() { Name = "Task 6", StartTime = new DateTime(2009, 02, 01) },
    new Task() { Name = "Task 7", StartTime = new DateTime(2009, 02, 09) }
};

// Now create the indexer.
BinarySearcher<Task> searcher = new BinarySearcher<Task>(tasks,
    (x, y) => Comparer<DateTime>.Default.Compare(x.StartTime, y.StartTime));

foreach (Task t in searcher.Between(
    new Task() { StartTime = new DateTime(2009, 02, 13) },
    new Task() { StartTime = new DateTime(2009, 02, 10) }))
{
    // Write.
    Console.WriteLine(t);
}