根据字符串过滤嵌套的对象数组

时间:2020-07-24 10:07:17

标签: javascript arrays javascript-objects

大家好,我有这个对象数组:

const example = {
    sections: [
        {
            id: 'something',
            sectionHeader: 'Something',
            content: [
                {
                    contentId: 'something1',
                    contentHeader: 'Lorem ipsum',
                },
                {
                    contentId: 'something2',
                    contentHeader: 'Lorem ipsum',
                },
            ],
        },
        {
            id: 'international',
            sectionHeader: 'International',
            content: [
                {
                    contentId: 'international1',
                    contentHeader: 'Mauris tempus vestibulum',
                },
            ],
        },
        {
            sectionId: 'home',
            sectionHeader: 'Home',
            content: [
                {
                    contentId: 'home1',
                    contentHeader: 'Etiam volutpat rhoncus',
                },
                {
                    contentId: 'home2',
                    contentHeader: 'Curabitur searchedValue mi lectus',
                },
                {
                    contentId: 'home3',
                    contentHeader: 'Orci varius natoque',
                },
            ],
        },
        {
            sectionId: 'city',
            sectionHeader: 'City',
            content: [
                {
                    contentId: 'city1',
                    contentHeader: 'Aliquam cursus',
                },
            ],
        },
    ],
};

我想基于 sectionHeader contentHeader

中的“搜索值”获得一个新的过滤数组:
const searchValue = 'searchedValue';

const filteredResults = example.sections.filter((section) => section.sectionHeader.toLowerCase().trim().includes(searchValue)
    || section.content.some((content) => content.contentHeader.toLowerCase().trim().includes(searchValue)))
    .filter((section) => section.content.length);

结果是该节,但具有所有三个内容对象(在本例中为“ home1”,“ home2”和“ home3”)。预期结果是仅包含搜索值('home2')的对象:

{
    sectionId: 'home',
    sectionHeader: 'Home',
    content: [
        {
            contentId: 'home2',
            contentHeader: 'Curabitur searchedValue mi lectus',
        },
    ],
},

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

您可以使用地图和过滤器来实现。

example.sections.map((section) => { 
  if(section.sectionHeader.toLowerCase().trim().includes(searchValue)) { 
    return section
  } 
  if (section.content.some((content) => content.contentHeader.toLowerCase().trim().includes(searchValue2))){ 
    let result = {...section}; 
    result.content= result.content.filter((content) => content.contentHeader.toLowerCase().trim().includes(searchValue2)); 
    return result
  } 
  return false;
}).filter(x=>x) 

结果

[ 
  { 
    sectionId: 'home',
    sectionHeader: 'Home',
    content: [ 
               { 
                  contentId: 'home2',
                  contentHeader: 'Curabitur searchedValue mi lectus' 
               } 
             ]
  } 
]

答案 1 :(得分:0)

我编写了一个快速功能,该功能将有助于解释每个步骤,希望可以使您走上正确的道路。这样写是为了让我可以更轻松地解释每个步骤。

步骤:

  • 我创建了一个接受搜索条件的函数。
  • 创建了所有节标题的地图
  • 创建了所有部分内容标题的地图
  • 遍历每个节标题,看是否符合搜索条件
  • 如果是,则返回整个部分
  • 如果不是,我们将遍历内容标题,并查看是否有任何值符合我们的搜索条件
  • 如果确实存储,则将这些索引存储在数组中
  • 返回该部分,并使用一个数组过滤器覆盖内容键,该过滤器将使搜索条件返回为true的所有索引保持为返回结果

如果您想减少代码的行数,我在下面写了一个更现代的版本

a = {'depth': {'buy': [{'orders': 1, 'price': 474.95, 'quantity': 1},
                   {'orders': 3, 'price': 474.9, 'quantity': 3},
                   {'orders': 1, 'price': 474.85, 'quantity': 2},
                   {'orders': 2, 'price': 474.7, 'quantity': 4}],
           'sell': [{'orders': 5, 'price': 475.1, 'quantity': 7},
                    {'orders': 2, 'price': 475.15, 'quantity': 2},
                    {'orders': 6, 'price': 475.2, 'quantity': 19},
                    {'orders': 4, 'price': 475.25, 'quantity': 4},
                    {'orders': 6, 'price': 475.3, 'quantity': 10}]}}

buy, sell = a['depth']['buy'], a['depth']['sell']

const example = {
  sections: [
    {
      id: "something",
      sectionHeader: "Something",
      content: [
        {
          contentId: "something1",
          contentHeader: "Lorem ipsum"
        },
        {
          contentId: "something2",
          contentHeader: "Lorem ipsum"
        }
      ]
    },
    {
      id: "international",
      sectionHeader: "International",
      content: [
        {
          contentId: "international1",
          contentHeader: "Mauris tempus vestibulum"
        }
      ]
    },
    {
      sectionId: "home",
      sectionHeader: "Home",
      content: [
        {
          contentId: "home1",
          contentHeader: "Etiam volutpat rhoncus"
        },
        {
          contentId: "home2",
          contentHeader: "Curabitur searchedValue mi lectus"
        },
        {
          contentId: "home3",
          contentHeader: "Orci varius natoque"
        }
      ]
    },
    {
      sectionId: "city",
      sectionHeader: "City",
      content: [
        {
          contentId: "city1",
          contentHeader: "Aliquam cursus"
        }
      ]
    }
  ]
};

function search(value) {
  const results = [];
  const sectionHeaders = example.sections.map(section => section.sectionHeader);
  const contentHeaders = example.sections.map(section =>
    section.content.map(content => content.contentHeader)
  );

  example.sections.forEach((_section, index) => {
    const foundIndexes = [];

    if (sectionHeaders[index] === value) {
      return results.push(example.sections[index]);
    }

    contentHeaders[index].forEach((header, index) => {
      if (header.includes(value)) {
        foundIndexes.push(index);
      }
    });

    if (foundIndexes.length !== 0) {
      return results.push({
        ...example.sections[index],
        content: example.sections[index].content.filter((_content, index) =>
          foundIndexes.includes(index)
        )
      });
    }
  });

  return results.length === 0 ? "No results found" : results;
}

console.log(search("searchedValue"));