Javascript - Как создать отфильтрованный вложенный массив

У меня есть объект массива здесь:

let businessList = [{
  name: "siAdmin",
  count: 52,
  children: [{
    name: "si1",
    count: 30,
    children: [{
      count: 10,
      name: "org1-1"
    }, {
      count: 14,
      name: "org1-2"
    }, {
      name: "org1-3",
      count: 6
    }]
  }, {
    name: "si2",
    count: 22,
    children: [{
      name: "org2-1",
      count: 22
    }]
  }]
}]

Я хочу составить отфильтрованный список, если count > 10, который будет выглядеть так:

filteredList = [{
  name: "siAdmin",
  count: 52,
  children: [{
    name: "si1",
    count: 30,
    children: [{
      count: 14,
      name: "org1-2"
    }]
  }, {
    name: "si2",
    count: 22,
    children: [{
      name: "org2-1",
      count: 22
    }]
  }]
}]

Как я могу достичь этого результата?

И если условие изменится на count > 23, это будет выглядеть так:

filteredList = [{
  name: "siAdmin",
  count: 52,
  children: [{
    name: "si1",
    count: 30,
    children: []
  }]
}]

Что вы пробовали, поделитесь с нами

Joseph 13.12.2020 09:48

Будет ли это si2 у детей?

Aalexander 13.12.2020 10:00
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
2
91
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

    let businessList = [{
  name: "siAdmin",
  count: 52,
  children: [{
    name: "si1",
    count: 30,
    children: [{
      count: 10,
      name: "org1-1"
    }, {
      count: 14,
      name: "org1-2"
    }, {
      name: "org1-3",
      count: 6
    }]
  }, {
    name: "si2",
    count: 22,
    children: [{
      name: "org2-1",
      count: 22
    }]
  }]
}]

function getData(input, number){
    let len = input.length;
    let ans = [];
    for(let i = 0; i < len; i++){
        if (input[i].count >= number){
            if (input[i].children){
                let data = getData(input[i].children,number);
            //ans.push(input[i]);
            input[i].children = data;
            ans.push(input[i])
            }
            else{
                ans.push(input[i]);
            }
        }
    }
    return ans;
}
getData(businessList,10)
getData(businessList,23)

выше функция должна работать

О, черт возьми, используйте forEach или карту

Aalexander 13.12.2020 10:00

@Alex Я избегаю для каждого или карты, потому что будет больше вызовов функций, кроме рекурсии, которые могут повлиять на стек

Abhishek 13.12.2020 10:01

Ваш код выдаст неправильный ответ, поскольку логика должна быть count>givenNumber, а не count>=givenNumber, как указано в вопросе. для getData(input, 10) не должно быть элементов со значением count = 10.

Md Sabbir Alam 13.12.2020 10:09

@ sabbir.alam спасибо, что указали на это, я полагал, что с этими вещами можно справиться, как только логика будет ясна.

Abhishek 13.12.2020 10:11

Кроме того, этот код не будет масштабироваться, если существует более 2 уровней вложенных дочерних элементов.

Md Sabbir Alam 13.12.2020 10:12

@sabbir.alam это должно работать для любого уровня вложенности, поскольку я называю это рекурсивно

Abhishek 13.12.2020 10:13

Виноват. Извините, не заметил рекурсивный вызов getData. :)

Md Sabbir Alam 13.12.2020 10:14

Абхишек и раствор саббира похожи. Я не вижу здесь никакой разницы в производительности. однако решение sabbir более чистое.

JustRaman 13.12.2020 10:27

@JustRaman, если вы посмотрите на размер стека вызовов, я думаю, что размер стека саббира будет больше.

Abhishek 13.12.2020 10:29

Вы можете использовать рекурсию следующим образом:

let businessList = [{
  name: "siAdmin",
  count: 52,
  children: [{
    name: "si1",
    count: 30,
    children: [{
      count: 10,
      name: "org1-1"
    }, {
      count: 14,
      name: "org1-2"
    }, {
      name: "org1-3",
      count: 6
    }]
  }, {
    name: "si2",
    count: 22,
    children: [{
      name: "org2-1",
      count: 22
    }]
  }]
}];

const filteredArray = (arr, countLimit) => {
  return arr.filter(item => {
    if (item.hasOwnProperty('children')) {
      item.children = filteredArray(item.children, countLimit);
    }
    return item.count > countLimit;
  })
};

console.info(filteredArray(JSON.parse(JSON.stringify(businessList)), 10));
console.info(filteredArray(JSON.parse(JSON.stringify(businessList)), 23));

console.info(businessList);

это не работает, потому что это испортит оригинальный бизнес-список в части item.children = filteredArray(item.children, countLimit). Я думаю, что метод push - единственное решение для меня.

Ryan Hsin 13.12.2020 12:29

Вы можете создать новую копию businessList, а затем отфильтровать этот массив копий, чтобы сохранить свой businessList нетронутым.

Md Sabbir Alam 13.12.2020 12:44

@RyanHsin обновил код, пожалуйста, посмотрите.

Md Sabbir Alam 14.12.2020 06:53
Ответ принят как подходящий

Наконец-то я нашел решение, не нарушая исходный объект, вот мой код:

let businessList = [{
  name: "siAdmin",
  count: 52,
  children: [{
    name: "si1",
    count: 30,
    children: [{
      count: 10,
      name: "org1-1"
    }, {
      count: 14,
      name: "org1-2"
    }, {
      name: "org1-3",
      count: 6
    }]
  }, {
    name: "si2",
    count: 22,
    children: [{
      name: "org2-1",
      count: 22
    }]
  }]
}];

function filteredBusiness(businessArr, count) {
  let arr = [];
  businessArr.forEach((business) => {
    let index = 0;
    let businessMatched = business.count > count
    if (businessMatched) {
      let {
        children,
        ...dataWithoutChildren
      } = business;
      arr.push({
        ...dataWithoutChildren
      });
      index = arr.length - 1;
      let hasChildren = business.children;
      if (hasChildren) {
        // arr[index].children = [];
        //check children matched
        let nextBusinessArr = filteredBusiness(
          business.children,
          count
        );
        if (nextBusinessArr) {
          arr[index].children = nextBusinessArr;
        }
      }
    }
  })
  return arr;
}
console.info(filteredBusiness(businessList, 10))

Другие вопросы по теме