Как создать функцию JavaScript для поиска объектов и массивов, вложенных друг в друга - PullRequest
0 голосов
/ 25 февраля 2019

У меня есть объект с вложенными массивами и объект, который выглядит следующим образом:

// Recursive nested objects & arrays:
var obj = {
  children: [{
      parentname: "level 0, Benny",
      children: [{
          parentname: "level 0.0, Stevey",
          children: [{
              parentname: "level 0.0.0, Betty",
              children: []
            },
            {
              parentname: "level 0.0.1, AFGNCAAP",
              children: [{
                parentname: "level 0.0.1.0, Moonman",
                children: []
              }]
            }
          ]
        },
        {
          parentname: "level 0.1, Oreo",
          children: []
        }
      ]
    },
    {
      parentname: "level 1, Jupiter",
      children: []
    }
  ]
};

// I am able to retrieve values with various length formulas:
console.log(obj.children[0].parentname); // level 0, Benny
console.log(obj.children[0].children[0].parentname); // level 0.0, Stevey
console.log(obj.children[0].children[0].children[0].parentname); // level 0.0.0, Betty
console.log(obj.children[0].children[0].children[1].parentname); // level 0.0.1, AFGNCAAP
console.log(obj.children[0].children[0].children[1].children[0].parentname); // level 0.0.1.0, Moonman
console.log(obj.children[0].children[1].parentname); // level 0.1, Oreo
console.log(obj.children[1].parentname); // level 1, Jupiter


// And I able to reduce formulas into functions...per level of nesting, example 1 level:
function getNameWorking1(name, level) {
  console.log(obj[name][level].parentname);
}
getNameWorking1(["children"], [1]) // level 1, Jupiter

// And example 2 levels:
function getNameWorking2(name, level) {
  console.log(obj[name][level[0]][name][level[1]].parentname);
}
getNameWorking2(["children"], [
  [0],
  [1]
]) // level 0.1, Oreo

// I am trying to create a single function that I can send a parameter with the sequence of property name & array values.  This does not work:
function getNameNotWorking(parameter) {
  console.log(obj[parameter].parentname);
}
getNameNotWorking("[children][1]");
getNameNotWorking("[children][0][children][1]");

Я пытаюсь создать одну функцию, в которую я могу отправить параметр с последовательностью имени свойства и значений массива.Эта последняя функция не работает.Любая помощь о том, как это сделать?

Кстати.У меня есть рекурсивная функция, которая работает для этого.Но он работает каждый раз, начиная с самого начала и просматривая каждый вложенный объект и массив, пока не будет найден искомый элемент.Кажется, что это может быть чрезмерно делать многократно.Поэтому я ищу метод для поиска объекта, когда я уже знаю его местоположение - через все значения дочернего массива.

Ответы [ 4 ]

0 голосов
/ 25 февраля 2019

Проверить JsonPath .Он обеспечивает чистый интерфейс для выбора атрибутов JSON без объектов, и для этого есть множество JavaScript SDK.

0 голосов
/ 25 февраля 2019

Ваша функция не работает, потому что она берет полную строку "[children][1]" и добавляет ее вместо parameter, то есть ищет obj["[children][1]"].parentname, который не определен.

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

Следовательно, ваша функция будет выглядеть примерно так:

function getNameNotWorking() {
  var returnValue = obj;
  for (let i = 0; i < arguments.length; i++) {
    returnValue = returnValue[arguments[i]];
  }
    console.log(returnValue);
}

Нажмите здесь для рабочего примера Codepen.

0 голосов
/ 25 февраля 2019

Вы можете сделать что-то подобное, используя регулярные выражения и reduce

const obj = {children:[{parentname:"level 0, Benny",children:[{parentname:"level 0.0, Stevey",children:[{parentname:"level 0.0.0, Betty",children:[]},{parentname:"level 0.0.1, AFGNCAAP",children:[{parentname:"level 0.0.1.0, Moonman",children:[]}]}]},{parentname:"level 0.1, Oreo",children:[]}]},{parentname:"level 1, Jupiter",children:[]}]}

const getNested = (object, str) => {
  let matches = [],
      match,
      regex = /\[(.*?)\]/g;

  while (match = regex.exec(str)) {
    matches.push(match[1]);
  }

  return matches.reduce((acc, key) => (acc || {})[key], object)
}

const nested = getNested(obj, "[children][0][children][1]")

console.log(nested)
  • Используйте /\[(.*?)\]/g для получения имен ключей в группе захвата ( Regex101 )
  • Использованиеexec, чтобы получить все имена ключей из группы захвата в массив

    // matches
    ["children", "0", "children", "1" ]
    
  • Использовать reduce для рекурсивного получения вложенного свойства объекта

0 голосов
/ 25 февраля 2019

Мне кажется, вам следует pass your parameters separated by white sapace вместо того, чтобы заключать квадратные скобки в скобки, чтобы облегчить анализ и решение .

И.здесь вы идете:)

function getNameWorking1(parameter, obj) {
  paramsList = parameter.split(' ').filter(prop => Boolean(prop)).map(prop => prop.trim());

  return paramsList.reduce((val, prop) => {
    return val[prop];
  }, obj).parentname;
}


//Working example:

var obj = {
  children: [{
      parentname: "level 0, Benny",
      children: [{
          parentname: "level 0.0, Stevey",
          children: [{
              parentname: "level 0.0.0, Betty",
              children: []
            },
            {
              parentname: "level 0.0.1, AFGNCAAP",
              children: [{
                parentname: "level 0.0.1.0, Moonman",
                children: []
              }]
            }
          ]
        },
        {
          parentname: "level 0.1, Oreo",
          children: []
        }
      ]
    },
    {
      parentname: "level 1, Jupiter",
      children: []
    }
  ]
};

console.log(getNameWorking1("children 1", obj));
console.log(getNameWorking1("children 0 children 1", obj));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...