У меня есть объект массива здесь:
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: []
}]
}]
Будет ли это si2 у детей?
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 или карту
@Alex Я избегаю для каждого или карты, потому что будет больше вызовов функций, кроме рекурсии, которые могут повлиять на стек
Ваш код выдаст неправильный ответ, поскольку логика должна быть count>givenNumber
, а не count>=givenNumber
, как указано в вопросе. для getData(input, 10)
не должно быть элементов со значением count = 10.
@ sabbir.alam спасибо, что указали на это, я полагал, что с этими вещами можно справиться, как только логика будет ясна.
Кроме того, этот код не будет масштабироваться, если существует более 2 уровней вложенных дочерних элементов.
@sabbir.alam это должно работать для любого уровня вложенности, поскольку я называю это рекурсивно
Виноват. Извините, не заметил рекурсивный вызов getData. :)
Абхишек и раствор саббира похожи. Я не вижу здесь никакой разницы в производительности. однако решение sabbir более чистое.
@JustRaman, если вы посмотрите на размер стека вызовов, я думаю, что размер стека саббира будет больше.
Вы можете использовать рекурсию следующим образом:
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 - единственное решение для меня.
Вы можете создать новую копию businessList, а затем отфильтровать этот массив копий, чтобы сохранить свой businessList нетронутым.
@RyanHsin обновил код, пожалуйста, посмотрите.
Наконец-то я нашел решение, не нарушая исходный объект, вот мой код:
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))
Что вы пробовали, поделитесь с нами