Различие между итератором и перечислителем

<!DOCTYPE html>
<html>    
<head>
    <title></title>
    <meta charset="UTF-8"> 
    <style type="text/css">
    </style>
    <script type="text/javascript">
        /*
          Let's simply represent this entire problem space differently. 
          Let's reconceive homogeneous, higher-order, JS arrays as two-
          dimensional, algebraic arrays instead of JS arrays, since JS 
          is not natively well-suited for this. 

          First, a few utility functions for handling arrays...
        */

        // calculate and return the sums of all the desired subarrays - 
        // relies on functions that treat JS arrays *differently*;
        // current implementations assumes that square subarrays of shape 
        // {size x size} are desired
        function calcSubSums(arr, size) {
            var sums = new Array();
            for (var i = 0; i < arr.length - size + 1; i++) {
                for (var j = 0; j < arr[i].length - size + 1; j++) {
                     sums.push(reduce(ravel(getSubArray(arr,[i,j],size))));
                }
            }
            return sums;
        };

        // for an array, arr, return subarray that starts at the top-left-
        // corner indexes tlc (top-row-index, left-column-index) for an 
        // extent of size on each dimension
        function getSubArray(arr, tlc, size) {
            var a = new Array();
            for (var i = tlc[0]; i < size + tlc[0]; i++) {
                var b = new Array();
                for (var j = tlc[1]; j < size + tlc[1]; j++) {
                    b.push(arr[i][j]);
                }
                a.push(b);
            }
            return a;
        };

        // convert a higher dimensional array into one-dimensional array 
        // that contains all of its elements, unpacking from top-to-bottom, 
        // left-to-right
        function ravel(arr, flat) {
            // If flat - accumulator array - not yet defined, create it.
            if ('undefined' == typeof flat) flat = new Array();
            // If arg is an array, iterate over the elements in index order.
            if (isArray(arr)) {
                // Call self recursively to get elements or process next, 
                // outermost level of nesting.
                for (var i = 0; i < arr.length; i++) { ravel(arr[i], flat); }
            }
            // Otherwise, just add simple element to accumulator.
            else flat.push( arr );
            // Return accumulated values.
            return flat;
        };

        // return a Boolean indicator of whether the argument is a JS array
        function isArray(a) {
            if ('undefined' == typeof a) {return false};
            return -1 != a.constructor.toString().indexOf('Array');
        };

        // place the operator {op} between the elements of a and evaluate the 
        // entire, resulting expression
        function reduce(a, op) {
            // Set default op (add/concatenate), if not given.
            if ('undefined' == typeof op) op = '+';
            // Initialize command to evaluate.
            var cmd = '';
            // Compose command string - concatenate each element with op.
            for (var i = 0; i < a.length; i++) {cmd += a[i] + op;}
            // Remove, extraneous, trailing instance of op and return evaluation.
            return eval(cmd.substring(0, cmd.length - op.length));
        };

        // now let's test it...
        window.onload = function() {
        // declare the test array
            var array = [
                [ 0,  0,  0, 0, 0, 0], 
                [ 5,  5,  5, 0, 0, 0], 
                [10, 10, 10, 0, 0, 0], 
                [ 0,  0,  0, 0, 0, 0], 
                [ 5,  5,  5, 0, 0, 0], 
                [10, 10, 10, 0, 0, 0]
            ];
        // calculate all of the sums of 3x3 subset arrays of our test array 
        // and write the totals to the console
            console.log(calcSubSums(array, 3));
        };
    </script>
</head>
<body></body>
</html>
71
задан Zero Piraeus 3 February 2015 в 18:57
поделиться

6 ответов

Итерация означает повторять некоторые шаги, в то время как перечисление означает проходить все значения в наборе значений. Так перечисление обычно требует некоторой формы повторения.

Таким образом перечисление является особым случаем итерации, где шаг получает значение от набора.

Отметьте "обычно" – перечисление может также быть выполнено рекурсивно, но рекурсия и повторение так тесно связаны, что я не заботился бы об этой небольшой разнице.

Можно также перечислить значения, которые Вы явно не храните в наборе. Например, можно перечислить натуральное число, начала, или безотносительно но Вы вычислили бы эти значения во время перечисления и не получили бы их от физического набора. Вы понимаете этот случай как перечисление виртуального набора с его значениями, определенными некоторой логикой.


Я предполагаю, что Reed Copsey понял. В C# существует два главных способа перечислить что-то.

  1. Реализация Enumerable и реализация класса IEnumerator
  2. Реализуйте итератор с yield оператор

Первый путь более трудно реализовать и объекты использования для перечисления. Второй путь легче реализовать и использует продолжения.

52
ответ дан T Graham 24 November 2019 в 12:59
поделиться

В C# 2 +, итераторы являются путем к компилятору для автоматической генерации IEnumerable и/или IEnumerable <T> интерфейсы для Вас.

Без итераторов необходимо было бы создать класс, реализовав IEnumerator, включая Текущий, MoveNext и Сброс. Это требует изрядного объема работы. Обычно, Вы создали бы частный класс что implemtented IEnumerator <T> для Вашего типа, затем yourClass. GetEnumerator () создал бы тот частный класс и возвратил бы его.

Итераторы являются путем к компилятору для автоматической генерации этого для Вас, с помощью простого синтаксиса (урожай). Это позволяет Вам реализовать GetEnumerator () непосредственно в Вашем классе без второго класса (IEnumerator) быть указанным Вами. Конструкция того класса, со всеми его участниками, сделана для Вас.

Итераторы являются очень дружелюбным разработчиком - вещи сделаны очень эффективным способом с намного меньшим усилием.

При использовании foreach эти два будут вести себя тождественно (если Вы пишете свой пользовательский IEnumerator правильно). Итераторы просто делают жизнь намного более простой.

43
ответ дан DaveInCaz 24 November 2019 в 12:59
поделиться

Для понимания итераторов, мы сначала должны понять перечислители.

Перечислители являются объектами специалиста, которые предоставляют один средства переместиться через заказанный список объектов по одному (тот же вид вещи иногда называют 'курсором'). Платформа.NET обеспечивает два важных интерфейса, касающиеся перечислителей: IEnumerator и IEnumerable. Объекты, которые реализуют IEnumerator, являются самостоятельно перечислителями; они поддерживают следующих членов:

  • свойство Current, которое указывает на позицию по списку

  • MoveNext метода, который перемещает Текущий объект один вдоль списка

  • Сброс метода, который перемещает Текущий объект в его исходное положение (который является перед первым объектом).

С другой стороны, Iterаtors реализуют enumerаtor pаttern..NET 2.0 представила iterаtor, который является а компилятором-mаnifested enumerаtor. Когда enumerаble возражают cаlls GetEnumerаtor, любой прямо или косвенно, компилятор generаtes аnd аn аppropriаte возвратов iterаtor объект. Optionаlly, iterаtor cаn быть а объединенный enumerаble аnd enumerаtor объект.

essentiаl компонент аn iterаtor блок является урожаем stаtement. Существует одна большая разница между iterаtors аnd enumerаtors: Iterаtors не реализуют метод Сброса. Cаlling метод Сброса на аn iterаtor cаuses аn исключение.

Точка итераторов должна позволить простое внедрение перечислителей. Куда метод должен возвратить или перечислитель или счетный класс для заказанного списка объектов, он записан, чтобы возвратить каждый объект в его правильном порядке с помощью оператора 'урожая'.

12
ответ дан Joshua 24 November 2019 в 12:59
поделиться

"Итераторы являются новой возможностью в C# 2.0. Итератор является методом, получите средство доступа или оператор, который позволяет Вам поддерживать foreach повторение в классе или структуре, не имея необходимость реализовывать весь интерфейс IEnumerable. Вместо этого Вы обеспечиваете просто итератор, который просто пересекает структуры данных в Вашем классе. Когда компилятор обнаружит Ваш итератор, он автоматически генерирует Ток, MoveNext и Расположит методы интерфейса IEnumerable или IEnumerable". - MSDN

3
ответ дан John Ellinwood 24 November 2019 в 12:59
поделиться

Перечисление имеет дело с объектами, в то время как повторение имеет дело со значениями только. Перечисление используется, когда мы используем векторную хеш-таблицу и т.д., в то время как повторение используется в цикле с условием продолжения для цикла и т.д. Я, никогда не имею не используют ключевое слово урожая, таким образом, я не мог сказать Вам.

2
ответ дан Kredns 24 November 2019 в 12:59
поделиться

What C # вызывает итератор , чаще (за пределами мира C #) называется генератором или функцией генератора (например, в Python). Функция генератора - это частный случай сопрограммы . Итератор (генератор) AC # - это специальная форма перечислителя (тип данных, реализующий интерфейс IEnumerable ).

Мне не нравится такое использование термина итератор для генератора C #, потому что он в такой же степени является перечислителем, как и итератором. Однако для Microsoft слишком поздно передумать.

Для контраста, учтите, что в C ++ итератор - это значение, которое используется в основном для доступа к последовательным элементам в коллекции. Его можно продвинуть, использовать для получения значения и протестировать, чтобы увидеть, достигнут ли конец коллекции.

20
ответ дан 24 November 2019 в 12:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: