Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   RecursiveIterator / Рекурсивный итератор (https://javascript.ru/forum/project/54054-recursiveiterator-rekursivnyjj-iterator.html)

nerv_ 01.03.2015 22:17

RecursiveIterator / Рекурсивный итератор
 
В продолжении темы Object.traverse() запилил рекурсивный итератор.

https://github.com/nervgh/recursive-iterator

Можно использовать как в ES5, так и в ES6 окружениях.
При использовании в ES6:
- поддерживает ES6 итерационные протоколы
- совместим с for...of циклом

Пример на es6:
var root = {
    object: {
        number: 1
    },
    string: 'foo'
};

for(let item of new RecursiveIterator(root)) {
    console.log(item.path.join('.'), item.node);
}

// or

for(let {parent, node, key, path, deep} of new RecursiveIterator(root)) {
    console.log(path.join('.'), node);
}

// or

for(let {node, path} of new RecursiveIterator(root, 1)) {
    console.log(path.join('.'), node);
}

Больше инфы здесь

Теги: js, javascript, walk, walker, recursive, recursion, iterator, iteratate, traverse, traversing, object, tree, json

nerv_ 04.03.2015 11:55

Обновил до версии 1.0.0.

- произведен глобальный рефакторинг в результате которого, инератор стал проще, читабельней и, надеюсь, быстрее
- введен параметр максимальной глубины погружения
- добавлены и описаны в документации методы
- добавлен коллбек onStepInto(), который позволяет гибко управлять обходом объектов
- возможность изменения объектов на месте
- больше тестов

kobezzza 04.03.2015 12:02

Можно использовать совместно с Collection, включая потоки :)

$C(new RecursiveIterator(root)).get({
  use: 'for of',
  thread: true,
  filter: 'someFilter1 && !someFilter2'
}).onComplete = function (data) {
  ...
};


:)

nerv_ 04.03.2015 18:22

Цитата:

Сообщение от kobezzza
Можно использовать совместно с Collection

круто :)

А разве Collection сам не может "рекурсивно" перебирать объекты?

melky 04.03.2015 18:44

Цитата:

Сообщение от nerv_
- больше тестов

покрытие ? :)

nerv_ 04.03.2015 19:49

Цитата:

Сообщение от melky
покрытие ?

Если речь идет о проценте покрытия, то я не знаю как его считать. Думаю, 70-80.
У kobezzza в coverage в collection заявлен процент 73. Любопытно, как он его получил :)

kobezzza 04.03.2015 21:27

Цитата:

А разве Collection сам не может "рекурсивно" перебирать объекты
Коробочных механизмов обхода деревьев нет, т.е. чтобы сделать это нужно явно задать рекурсию, например рекурсивный reduce, и т.д. или использовать итератор в качестве данных (как в твоём случае).

Цитата:

У kobezzza в coverage в collection заявлен процент 73. Любопытно, как он его получил
На самом деле где-то 85%, просто лень было PhantomJS заряжать для тестов. Покрытие оценивается библиотекой Istanbul, но следует заметить, что это покрытие кода, а не вариантов его использования. Сейчас в Collection около 1.5к тестов.

melky 04.03.2015 23:06

Цитата:

Сообщение от kobezzza
На самом деле где-то 85%, просто лень было PhantomJS заряжать для тестов. Покрытие оценивается библиотекой Istanbul, но следует заметить, что это покрытие кода, а не вариантов его использования. Сейчас в Collection около 1.5к тестов.

для ES6 я пользуюсь isparta... istanbul не умеет ES6 инструментировать

kobezzza 05.03.2015 00:29

Цитата:

Сообщение от melky (Сообщение 359645)
для ES6 я пользуюсь isparta... istanbul не умеет ES6 инструментировать

А у меня babel + istanbul, а isparta тоже включает транслятор что ли?

upd: глянул доку, так и есть - это просто istanbul + babel :)

nerv_ 05.03.2015 11:41

Цитата:

Сообщение от kobezzza
Коробочных механизмов обхода деревьев нет

кажется, я понял почему :)

kobezzza, зарегай свои наработки в npm & bower для продвижения (если еще этого не сделал.) и напиши про это в readme

kobezzza 05.03.2015 11:43

Цитата:

kobezzza, зарегай свои наработки в npm & bower для продвижения (если еще этого не сделал.) и напиши про это в readme
Дык, они 100 лет уже там :)

melky 05.03.2015 15:01

Цитата:

Сообщение от kobezzza
upd: глянул доку, так и есть - это просто istanbul + babel

а в результатах покрытия чистый код на ES6, а не результат babel

kobezzza 05.03.2015 15:23

Цитата:

Сообщение от melky (Сообщение 359716)
а в результатах покрытия чистый код на ES6, а не результат babel

Хм, надо глянуть.

melky 05.03.2015 17:20

Цитата:

Сообщение от kobezzza (Сообщение 359724)
Хм, надо глянуть.

preLoader для webpack
http://javascript.ru/forum/project/5...er-loader.html

clecar 12.03.2015 16:35

Что там есть. Но я ничего не понял. Попроще для таких как я(слесарь ремонтник больших металлорежущиж станков).

nerv_ 14.03.2015 09:58

Упрощенный пример глубокого копирования (клонирования) объекта (он же в песоцнице):
var toString = Object.prototype.toString;
var isObject = RecursiveIterator.isObject;

/**
 * @param {*} any
 * @returns {String}
 */
function getType(any) {
    return toString.call(any).slice(8, -1);
}

/**
 * @param {*} any
 * @returns {*}
 */
function shallowCopy(any) {
    var type = getType(any);
    switch (type) {
        case 'Object':
            return {};
        case 'Array':
            return [];
        case 'Date':
            return new Date(any);
        case 'RegExp':
            return new RegExp(any);
        case 'Number':
        case 'String':
        case 'Boolean':
        case 'Undefined':
        case 'Null':
            return any;
        default:
            return any.toString();
    }
}

/**
 * @param {*} any
 * @param {Boolean} [deep]
 * @returns {*}
 */
function copy(any, deep = false) {
    if (!deep || !isObject(any)) {
        return shallowCopy(any);
    }

    var map = new Map();
    var rootNode = shallowCopy(any);
    map.set(any, rootNode);

    for(var {parent, node, key} of new RecursiveIterator(any, 1, true)) {
        var parentNode = map.get(parent);
        var cloneNode = shallowCopy(node);
        parentNode[key] = cloneNode;
        map.set(node, cloneNode);
    }

    map.clear();

    return rootNode;
}

// ---------------------------------
// USAGE
// ---------------------------------

var some = {
    foo: {
        bar: 1
    }
};

var clone = copy(some, true);
alert(JSON.stringify(clone));
alert(clone === some);

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

nerv_ 22.03.2015 18:27

Превращаем рекурсивный итератор в простой итератор :)
import RecursiveIterator from 'your_path';

class Iterator extends RecursiveIterator {
    constructor(iterable) {
        super(iterable, 1, false, 1);
    }
}

итерируем

import Iterator from 'your_path';


for(let {node, key} of new Iterator([1, 2, 3])) {
    console.log(node);
}

for(let {node, key} of new Iterator(document.getElementsByTagName('h1'))) {
    console.log(node, key);
}

nerv_ 31.05.2015 20:10

Обновил до версии 1.3

* еще больше сжатия в min версии
* утилиты вынесены в отдельные модули
* добавлена карта документации (сама дока переехала в вики)
* добавлена книга рецептов

Отдельно хотелось бы сказать про рецепт DomIterator, который показывает, как на основе {RecursiveIterator} создавать любой необходимый вам итератор, подтверждая простоту, лаконичность и расширяемость {RecursiveIterator} :)

рони 31.05.2015 23:31

nerv_,
:thanks:

nerv_ 14.06.2015 16:47

Обновил до версии 2.0

- удалено несколько лишних вычислений на этапе инициализации (создание итератора теперь обходиться очень дешево)
- переименовано пару методов (дабы внести очевидность); изменены аргументы одного метода (объект вместо списка) Апи почти стабилизировалось :)
- добавлены примеры реализации алгоритмов неинформированного поиска на базе рекурсивного итератора

nerv_ 28.06.2015 23:11

Игра "восемь"
 
Решение головоломки "восемь" (как пятнашки, только матрица 3x3) с помощью эвристического поиска на базе рекурсивного итератора http://jsfiddle.net/uoskm6bq/9/

Для визаулизации применяется Vue.js & Bootstrap.css

По идее, должно работать и для пятнашек, не проверял :)

Исходники

nerv_ 20.07.2015 10:00

To Query String
 
Добавлен рецепт конвертации объекта/массива в строку запроса

nerv_ 21.06.2017 12:05

Два года почти прошло :)

Любопытства ради решил взглянуть на статистку в npm:
Цитата:

Stats
2,791 downloads in the last day
13,586 downloads in the last week
55,865 downloads in the last month
В целом неплохо. Я бы даже сказал немного неожиданно) Кто бы мог подумать, что стольким людям захочется итерировать :D
На самом деле все просто: это низкоуровневый пакет (если можно так выразится), который другие разработчики используют в своих проектах. Как и задумывалось изначально.
До сих пор считаю его далеко не идаельным. Но, если бы я держал его всё это время в загашнике, то он в принципе бы не увидел свет)

рони 21.06.2017 12:14

nerv_,
:thanks:

Rasy 21.06.2017 21:53

Цитата:

Сообщение от nerv_
В целом неплохо. Я бы даже сказал немного неожиданно)

Бахнуть код который может понадобится такому большому кол-ву девелоперов - это то ради чего стоит работать. Лучшая награда.
Цитата:

Сообщение от nerv_
До сих пор считаю его далеко не идаельным.

Вряд ли кто-то своим кодом полностью удовлетворен)


Часовой пояс GMT +3, время: 10:03.