搜索嵌套的对象数组并返回全双亲作为结果| javascript

时间:2019-04-15 06:41:03

标签: javascript

您好,我需要一些帮助来完成我的功能。我已经成功编写了一个递归函数来遍历嵌套对象并找到结果。但是,如果孩子的所有孩子都通过了考试,我很难添加整个父母。我有以下代码:

const myObj = [
  {
    name: '1',
    pages: [
      {
        name: '1.1',
        pages: []
      },
      {
        name: '1.2',
        pages: []
      },
    ]
  },
  {
    name: '2',
    pages: []
  },
  {
    name: '3',
    pages: []
  }
]

function searchPages(searchQuery, obj) {
  let searchResults = [];
  for (let i = 0; i < obj.length; i++) {
    let item = searchString(obj[i], searchQuery);

    if (item) {
      searchResults.push(item);
    }
  }
  return searchResults;
}

function searchString(obj, string) {
  if (obj.name.includes(string)) {
    return obj;
  }

  for (let i = 0; i < obj.pages.length; i++) {
    const possibleResult = searchString(obj.pages[i], string);
    if (possibleResult) {
      return possibleResult;
    }
  }
}

let searchResults = searchPages('1.1', myObj);
console.log(searchResults);

这会正确搜索嵌套数组并给出正确的结果:

  {
    "name": "1.1",
    "pages": []
  }

但是我想返回整个父对象,而不仅仅是子对象。因此,预期结果是这样的:

  {
    name: '1',
    pages: [
      {
        name: '1.1',
        pages: []
      },
      {
        name: '1.2',
        pages: []
      },
    ]
  }

有人可以帮我修改我的功能来实现吗?谢谢!

请记住,这只是一个小对象,仅出于可读性目的。我的实际对象将具有更多的级别和属性。

4 个答案:

答案 0 :(得分:3)

您可以采用递归方法,并检查嵌套数组是否具有所需名称。

function searchPages(array, string) {
    const find = ({ name, pages }) => name.includes(string) || pages && pages.some(find);
    return array.filter(find);
}

const
    data = [{ name: '1', pages: [{ name: '1.1', pages: [] }, { name: '1.2', pages: [] }] }, { name: '2', pages: [] }, { name: '3', pages: [] }],
    searchResults = searchPages(data, '1.1');

console.log(searchResults);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:2)

这是一种可能的方法,对顶部数组使用.filter,然后递归调用.some

const myObj = [
  {
    name: '1',
    pages: [
      {
        name: '1.1',
        pages: []
      },
      {
        name: '1.2',
        pages: []
      },
    ]
  },
  {
    name: '2',
    pages: []
  },
  {
    name: '3',
    pages: []
  }
];

const searchPages = (nameToFind, obj) => obj.filter(pageContainsName(nameToFind));
const pageContainsName = nameToFind => ({ name, pages }) => (
  name === nameToFind || pages.some(pageContainsName(nameToFind))
);
let searchResults = searchPages('1.1', myObj);
console.log(searchResults);

答案 2 :(得分:1)

如果要返回父级object而不是搜索的object,则只需更改searchString()实现,以将父级作为第三个参数,然后将其返回如果找到所需的string

function searchPages(searchQuery, obj) {
  let searchResults = [];
  for (let i = 0; i < obj.length; i++) {
    let item = searchString(obj[i], searchQuery, obj);

    if (item) {
      searchResults.push(item);
    }
  }
  return searchResults;
}

function searchString(obj, string, parent) {
  if (obj.name.includes(string)) {
    return parent;
  }

  for (let i = 0; i < obj.pages.length; i++) {
    const possibleResult = searchString(obj.pages[i], string, obj);
    if (possibleResult) {
      return possibleResult;
    }
  }
}

这样,您将始终将父母考虑在内。

演示:

const myObj = [
  {
    name: '1',
    pages: [
      {
        name: '1.1',
        pages: [
          {
            name: '1.1.1',
            pages: []
          }
        ]
      },
      {
        name: '1.2',
        pages: []
      },
    ]
  },
  {
    name: '2',
    pages: []
  },
  {
    name: '3',
    pages: []
  }
]

function searchPages(searchQuery, obj) {
  let searchResults = [];
  for (let i = 0; i < obj.length; i++) {
    let item = searchString(obj[i], searchQuery, obj);

    if (item) {
      searchResults.push(item);
    }
  }
  return searchResults;
}

function searchString(obj, string, parent) {
  if (obj.name.includes(string)) {
    return parent;
  }

  for (let i = 0; i < obj.pages.length; i++) {
    const possibleResult = searchString(obj.pages[i], string, obj);
    if (possibleResult) {
      return possibleResult;
    }
  }
}

let searchResults = searchPages('1.1.1', myObj);
console.log(searchResults);

答案 3 :(得分:1)

这是我的方法,其中.filter-myObj.find-嵌套具有给定名称的嵌套页面

const myObj = [
  {
    name: '1',
    pages: [
      {
        name: '1.1',
        pages: []
      },
      {
        name: '1.2',
        pages: []
      },
    ]
  },
  {
    name: '2',
    pages: []
  },
  {
    name: '3',
    pages: []
  }
];

const searchPages = (name, arr) => arr.filter(
  ({ pages }) => pages.find(page => page.name === name)
) 

let searchResults = searchPages('1.1', myObj);
console.log(searchResults);