Объединение объектов по братьям и сестрам в javascript

#javascript #chaining #lodash

#javascript #объединение в цепочки #Lodash

Вопрос:

У меня простая проблема: есть объект, элементы которого имеют массив своих соединений. Только для братьев и сестер:

 var obj = {
    1: [2],
    2: [1,3],
    3: [2,4],
    4: [3],

    5: [6],
    6: [5]
}
  

Существует два соединения, первые 4 связаны друг с другом, а также 5. и 6. тоже. Я бы получил список, зависящий от выбранного элемента, о том, кто связан друг с другом. Итак, если я выберу giveMeTheListOfSiblingIn(3) , я хотел бы получить этот список: [1,2,3,4] .

Это не сложно, потому что я не могу найти решение, всегда избегайте бесконечного цикла. Вот моя попытка в JSFiddle, я использовал фреймворк Lo-Dash, но вам это не обязательно.

Заранее спасибо!

Комментарии:

1. Почему 3 в выводе giveMeTheListOfSiblingIn(3) ?

2. Это пример. Поэтому, если я выбираю один из элементов, я должен получить его братьев и сестер. Если параметр 5, я должен получить [5,6] . Если параметр 1,2,3 или 4, я должен получить [1,2,3,4]

Ответ №1:

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

 var obj = {
    1: [2],
    2: [1,3],
    3: [2,4],
    4: [3],
    5: [6],
    6: [5]
}
list = [];
function call(id) {

    if (list.indexOf(id) == -1) {
       list.push(id);
       obj[id].forEach(call)
    }
    return list;
}

var result = call(6);

console.log(result);
  

http://jsfiddle.net/9L5s6/1/

Ответ №2:

Если вы не хотите застревать в цикле и перебирать всех братьев и сестер, вы можете посмотреть на это как на какой-то a tree , где ваш first visited узел является a root . В этом случае вы бы использовали recursive algorithm для перемещения по дереву. Однако вам нужно будет сохранить посещенные узлы, чтобы вы не посещали их снова.

Пример: допустим, сначала вы посещаете 3-й узел.

 3 has two connections, visit 2.
2 -> visit 1.
1 points to 2, but 2 is visited so return.
2 (because 2 points to 1) also points to 3, but 3 is visited so return.
3 also points to 4, visit 4.
4 points to 3, 3 is visited so return.
3 no more connections and also a root node so tree walking is complete.
  

Надеюсь, это поможет :).

Ответ №3:

 var obj = {
    1: [2],
    2: [1,3],
    3: [2,4],
    4: [3],

    5: [6],
    6: [5]
}

//initiallly all siblings will be an empty string
var giveMeTheListOfSiblingIn = function(index, allSiblings) {
    //get imidiate or directly connected siblings
    var _mySiblings = obj[index];
    var me = index
    for(var i=0;i<_mySiblings.length;i  ) {
        //if sibling is already added, don't add it again
        //ignore already found sibling and sibling of its sibling as its
        //siblings are already capture. See  push line below
        if(allSiblings.indexOf(_mySiblings[i]) == -1 amp;amp; _mySiblings[i] != me) {
            //push currently found sibling
            allSiblings.push(_mySiblings[i])
            //get siblings of currently found sibling and pass all the siblings found yet
            //so that it will not search again for the same sibling
            allSiblings = giveMeTheListOfSiblingIn(_mySiblings[i], allSiblings)
        }
    }
    return allSiblings
}
  

Вывод — тестовые примеры

 giveMeTheListOfSiblingIn(2, [])
//output [1, 2, 3, 4]

giveMeTheListOfSiblingIn(6, [])
//output [5, 6]