Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 24.08.2014, 14:15
Интересующийся
Отправить личное сообщение для frying Посмотреть профиль Найти все сообщения от frying
 
Регистрация: 11.02.2013
Сообщений: 12

js рекурсивная функция с for.. in циклом
В общем есть рекурсивная функция, ей передаётся объект и текстовый шаблон, функция должна вернуть свойства объекта и всех своих объектов если в их значении содержится текстовый шаблон.

<html>
<head>
    <meta charset="utf-8"> 
    <title>Test html with js tasks</title>
    <script type="text/javascript" src='./2.js'></script>
</head>
<body>
    <script type="text/javascript">
        var objSample = {
            "glossary": {
                "title": "example glossary",
                "GlossDiv": {
                    "title": "S",
                    "GlossList": {
                        "GlossEntry": {
                            "ID": "SGML",
                            "SortAs": "SGML",
                            "GlossTerm": "Standard Generalized Markup Language",
                            "Acronym": "SGML",
                            "Abbrev": "ISO 8879:1986",
                            "GlossDef": {
                                "para": "A meta-markup language, used to create markup languages such as DocBook.",
                                "GlossSeeAlso": ["GML", "XML"]
                            },
                            "GlossSee": "markup"
                        }
                    }
                }
            }
        };
        findProperty(objSample, 'SGML');
    </script>
    Pikabu
</body>
</html>


и сама функция:
function findProperty(obj, propContentPart) {
    for (var key in obj) {
        var value = obj[key];
        if (typeof value === 'object') {
            if (findProperty(value, propContentPart)) {
                console.log(key);
                return true;
            }
        } else {
            if (value.indexOf(propContentPart) > -1){
                console.log(key);
                return true;
            }
        }
    }
}


Получается следующий вывод:
ID
GlossEntry
GlossList
GlossDiv
glossary

Это цепочка(путь) до свойства, которое будет удовлетворять шаблону ( по-хорошему должно быть glossary->GlossDiv->GlossList->GlossEntry->Id). Проблема в том, что кроме него должны быть ещё свойства SortAs и Acronym со своими путями.

Похоже на то, что когда в стеке рекурсии появляется первый return, то по достижении изначального for in он сразу выходит из него. Понятно что он должен выходить из того уровня рекурсии, в котором он появился. Вопрос: почему он не продолжает идти по следующим свойствам?
Ответить с цитированием
  #2 (permalink)  
Старый 24.08.2014, 15:33
Аватар для Erolast
Профессор
Отправить личное сообщение для Erolast Посмотреть профиль Найти все сообщения от Erolast
 
Регистрация: 24.09.2013
Сообщений: 1,436

Все дело в 7 строке. После того, как свойство с нужным значением найдено, функция заканчивается.
Ответить с цитированием
  #3 (permalink)  
Старый 25.08.2014, 09:28
Интересующийся
Отправить личное сообщение для frying Посмотреть профиль Найти все сообщения от frying
 
Регистрация: 11.02.2013
Сообщений: 12

Вопрос: почему так? Если return происходит на одном из уровней функции, почему он просто не переходит на следующую итерацию предыдущего уровня рекурсии?
Ответить с цитированием
  #4 (permalink)  
Старый 25.08.2014, 09:30
Аватар для ksa
ksa ksa на форуме
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,205

Сообщение от frying
Если return происходит на одном из уровней функции, почему он просто не переходит на следующую итерацию предыдущего уровня рекурсии?
Дело не в уровне... А в расположении того ретурна.
Возвращаться-то он возвращается... А вот продолжения перебора свойств прекращается.
Ответить с цитированием
  #5 (permalink)  
Старый 25.08.2014, 10:25
Аватар для ksa
ksa ksa на форуме
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,205

Сообщение от frying
по-хорошему должно быть glossary->GlossDiv->GlossList->GlossEntry->Id
Как вариант, для получения всех таких цепочек...

var objSample = {
	"glossary": {
		"title": "example glossary",
		"GlossDiv": {
			"title": "S",
			"GlossList": {
				"GlossEntry": {
					"ID": "SGML",
					"SortAs": "SGML",
					"GlossTerm": "Standard Generalized Markup Language",
					"Acronym": "SGML",
					"Abbrev": "ISO 8879:1986",
					"GlossDef": {
						"para": "A meta-markup language, used to create markup languages such as DocBook.",
						"GlossSeeAlso": ["GML", "XML"]
					},
					"GlossSee": "markup"
				}
			}
		}
	}
};
findProperty(objSample, 'SGML');
function findProperty(obj, propContentPart, History) {
	History=(History)? History: '';
	var val;
    for (var key in obj) {
        var value = obj[key];
        if (typeof value === 'object') {
			val=(History=='')? key: History+'->'+key;
            findProperty(value, propContentPart, val);
        } else {
            if (value.indexOf(propContentPart) > -1){
				val=(History=='')? key: History+'->'+key;
                alert(val);
            };
        };
    };
};
Ответить с цитированием
  #6 (permalink)  
Старый 25.08.2014, 10:46
Интересующийся
Отправить личное сообщение для frying Посмотреть профиль Найти все сообщения от frying
 
Регистрация: 11.02.2013
Сообщений: 12

ksa, спасибо. Только мне не понятно почему он прекращается. Извините, если кажусь тугодумом, но постараюсь объяснить как я это понимаю:
1. Начинаем перебирать свойства из цикла.
2. Заходим в эту же функцию, появляется новый уровень рекурсии.
3. Начинаем перебирать свойства из цикла.
4. Заходим в эту же функцию, появляется новый уровень рекурсии.
итд...
n. Попадаем на return. Выходим из функции на n'ом уровне рекурсии. Попадаем на предыдущий уровень и продолжаем перебирать функции из него.
Почему он сразу выходит из всех уровней?

ksa, Вы говорите, что всё дело в расположении return, что не так с ним?
Ответить с цитированием
  #7 (permalink)  
Старый 25.08.2014, 10:50
Аватар для ksa
ksa ksa на форуме
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,205

Сообщение от frying
Попадаем на предыдущий уровень и продолжаем перебирать функции из него.
Вот тут уже не так.
Перебор прекратиться если найдено свойство с нужным содержанием... Там ведь ретурн стоит.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Не получается вставить код js в HTML garmoni Элементы интерфейса 3 05.09.2013 05:56
PHP ФУНКЦИЯ В JS Облом Общие вопросы Javascript 1 08.08.2011 00:41
Почему не работает функция js? oliwin Общие вопросы Javascript 2 11.07.2010 13:16
JS функция не возращает параметр .. Arfey Общие вопросы Javascript 2 10.06.2010 13:19
Не вызывается функция из внешнего js Danie Ваши сайты и скрипты 6 14.10.2009 11:19