Фильтровать вложенный json на основе двух условий

#javascript #json #filter

#javascript #json #Фильтр

Вопрос:

У меня есть вложенный массив json, как показано ниже:

 [  
   {  
      "filename":"Vegetable",
      "children":[  
         {  
            "filename":"Juicy",
            "children":[  
               {  
                  "filename":"Tomato",
                  "type":"ts1"
               },
               {  
                  "filename":"Carrot",
                  "type":"ts2"
               },
               ,
               {  
                  "filename":"Onion",
                  "type":"ts3"
               }
            ]
         },
         {  
            "filename":"Sweet",
            "children":[  
               {  
                  "filename":"Potato",
                  "type":"ts4"
               },
               {  
                  "filename":"Water melon",
                  "type":"ts"
               }
            ]
         }
      ]
   },
   { filename:"Fruits"..........
   },....
]
  

Мне нужно отфильтровать массив таким образом, чтобы выполнить следующие условия:

  1. Filename = Заданный Juicy (он также может быть сладким, я имею в виду, что уровень 2-го уровня массива)
  2. При этом будет текст фильтра, предположим, что это 't' . Тогда он должен соответствовать именам файлов Tomato, Carrot , поскольку он содержит t

Основываясь на нижеприведенных условиях, ожидаемый результат

 [  
   {  
      "filename":"Vegetable",
      "children":[  
         {  
            "filename":"Juicy",
            "children":[  
               {  
                  "filename":"Tomato",
                  "type":"ts1"
               },
               {  
                  "filename":"Carrot",
                  "type":"ts2"
               }
            ]
         },
         {  
            "filename":"Sweet",
            "children":[  
               {  
                  "filename":"Potato",
                  "type":"ts4"
               },
               {  
                  "filename":"Water melon",
                  "type":"ts"
               }
            ]
         }
      ]
   },
   { filename:"Fruits"..........
   },....
]
  

т. е. он должен удалять

 {  "filename":"Onion",
   "type":"ts3"
 }
  

Поскольку onion не содержит ‘t’.

Я пробовал использовать filter, map с использованием функций со стрелками, но работает не так, как ожидалось.

Я попробовал функцию filterby =(childname, filterText).filter =>{...}

Пожалуйста, направь меня…

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

1. Не могли бы вы немного лучше объяснить первое условие?

2. Ожидаемый результат имеет оба Sweet и Juicy . Можете ли вы уточнить, что вы подразумеваете под «Имя файла: Juicy —-> Который может быть сладким»

3. @ Teneff обновлено

4. @ adiga обновил вопрос для большей ясности

5. Так что, переменная — это просто буква t ?

Ответ №1:

Я пришел с одним решением, которое использует два вложенных Array.map() и Array.filter() на последнем уровне дочерних элементов:

 const input = [  
 {  
   "filename":"Vegetable",
   "children":[  
     {  
       "filename":"Juicy",
       "children":[  
         {"filename":"Tomato", "type":"ts1"},
         {"filename":"Carrot", "type":"ts2"},
         {"filename":"Onion", "type":"ts3"}
       ]
     },
     {  
       "filename":"Sweet",
       "children":[  
         {"filename":"Potato", "type":"ts4"},
         {"filename":"Water melon", "type":"ts"}
       ]
     }
   ]
 },
 {
   "filename":"Fruits",
   "children": []
 }
];

const filterBy = (arr, childname, filterText) =>
{
    return arr.map(({filename, children}) =>
    {
        return {filename, children: children.map(({filename, children}) =>
        {
           if (filename === childname)
               return {filename, children: children.filter(
                   x => x.filename.match(filterText)
               )};
           else
               return {filename, children};
        })};
    });
}

console.log(
  "Filter the Juits by text 't': ",
  filterBy(input, "Juicy", "t")
);

console.log(
  "Filter the Sweet by text 'r': ",
  filterBy(input, "Sweet", "r")
);  
 .as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}  

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

1. @androidGenX Добро пожаловать, в обновлениях были исправлены некоторые ошибки. Кроме того, я считаю, что может быть более простое решение, если вы используете библиотеку, подобную Lodash . Может быть, кто-то придет с ответом, используя его в будущем.