У меня есть массив с родителем и дочерним элементом и расходом дочернего элемента (расходов может быть больше 3-х). Я хочу отфильтровать список, сгруппированный по родителям, и показать родителям, где комбинация детей имеет сочетание положительных и отрицательных расходов. Отфильтруйте родителей, если у них есть только положительные или только отрицательные расходы.
Входной массив:
let inputArray1 = [
{
'parent':'A',
'child':'RST',
'expense1':1,
'expense2':2,
'expense3':3,
},
{
'parent':'A',
'child':'EST',
'expense1':4,
'expense2':5,
'expense3':6,
},
{
'parent':'A',
'child':'QST',
'expense1':4,
'expense2':2,
'expense3':6,
},
{
'parent':'B',
'child':'EST',
'expense1':1,
'expense2':2,
'expense3':-3, //. <----Negative Expense
},
{
'parent':'B',
'child':'VST',
'expense1':6,
'expense2':2,
'expense3':3,
},
{
'parent':'B',
'child':'NST',
'expense1':3,
'expense2':8,
'expense3':7,
},
{
'parent':'C',
'child':'UST',
'expense1':-8,
'expense2':-2,
'expense3':3, //<--- Positive Expense
},
{
'parent':'C',
'child':'PST',
'expense1':-6,
'expense2':-5,
'expense3':-3,
},
{
'parent':'C',
'child':'LST',
'expense1':-3,
'expense2':-8,
'expense3':-7,
},
{
'parent':'D',
'child':'WST',
'expense1':-8,
'expense2':-2,
'expense3':-3,
},
{
'parent':'D',
'child':'CST',
'expense1':-6,
'expense2':-5,
'expense3':-3,
},
{
'parent':'D',
'child':'KST',
'expense1':-3,
'expense2':-8,
'expense3':-7,
}
]
Выходной массив: он должен иметь только B и C, поскольку они имеют комбинацию положительных и отрицательных расходов среди дочерних расходов.
let inputArray1 = [
{
'parent':'B',
'child':'EST',
'expense1':1,
'expense2':2,
'expense3':-3,
},
{
'parent':'B',
'child':'VST',
'expense1':6,
'expense2':2,
'expense3':3,
},
{
'parent':'B',
'child':'NST',
'expense1':3,
'expense2':8,
'expense3':7,
},
{
'parent':'C',
'child':'UST',
'expense1':-8,
'expense2':-2,
'expense3':3,
},
{
'parent':'C',
'child':'PST',
'expense1':-6,
'expense2':-5,
'expense3':-3,
},
{
'parent':'C',
'child':'LST',
'expense1':-3,
'expense2':-8,
'expense3':-7,
},
]
Что, если у родителя есть дети только с положительными расходами, а другие дети только с отрицательными расходами, и ни у одного из детей смешанные расходы? Вы включаете этого родителя или нет?
Родитель с детьми, имеющий все положительные или все отрицательные расходы, отфильтровывается. Если комбинация расходов по всем дочерним элементам содержит хотя бы один расход, который является либо положительным, либо отрицательным (т. е. все расходы относятся к разным типам), то все они отображаются в наборе результатов. Подобно тому, как это показано в примере B и C, в выводе отображаются все их дочерние элементы, поскольку был один расход, который был другого типа.
Почему в вашем выходном массиве нет дочернего элемента KST?
Получите набор уникальных родителей. Для каждого уникального родителя найдите всех дочерних элементов, получите все расходы (т. е. там, где имя свойства начинается со слова «расходы»), извлеките все значения расходов и проверьте, есть ли сочетание положительных и отрицательных чисел. Затем, если родитель соответствует этому тесту, извлеките все записи этого родителя и включите их в результат.
const data = [{"parent":"A","child":"RST","expense1":1,"expense2":2,"expense3":3},{"parent":"A","child":"EST","expense1":4,"expense2":5,"expense3":6},{"parent":"A","child":"QST","expense1":4,"expense2":2,"expense3":6},{"parent":"B","child":"EST","expense1":1,"expense2":2,"expense3":-3},{"parent":"B","child":"VST","expense1":6,"expense2":2,"expense3":3},{"parent":"B","child":"NST","expense1":3,"expense2":8,"expense3":7},{"parent":"C","child":"UST","expense1":-8,"expense2":-2,"expense3":3},{"parent":"C","child":"PST","expense1":-6,"expense2":-5,"expense3":-3},{"parent":"C","child":"LST","expense1":-3,"expense2":-8,"expense3":-7},{"parent":"D","child":"WST","expense1":-8,"expense2":-2,"expense3":-3},{"parent":"D","child":"CST","expense1":-6,"expense2":-5,"expense3":-3},{"parent":"B","child":"KST","expense1":-3,"expense2":-8,"expense3":-7}]
console.info([...new Set(data.map(i=>i.parent))]
.filter(parent=>data.filter(i=>i.parent===parent)
.flatMap(i=>Object.entries(i).filter(([k])=>k.startsWith('expense'))
.map(([k,v])=>Math.abs(v)===v))
.reduce((a,c,i,r)=>a || i>0 && c!==r[i-1],false))
.flatMap(parent=>data.filter(i=>i.parent===parent)))
Фильтрация массивов может быть немного сложной, если вы не разбираетесь в функциях высшего порядка (https://eloquentjavascript.net/05_higher_order.html). По сути, они абстрагируют код, который мы могли бы сделать, используя циклы if и else, чтобы удалить или добавить то, что мы хотим.
Я не совсем понимаю ваш вопрос, потому что результат, который я сделал, отличается от того, что вы хотите, но я придерживался исключения всего, что было только положительным или только отрицательным.
К счастью, это не проблема, потому что вы можете реализовать свою собственную логику в той части функции, которую я для этого оставил закомментированной.
В основном то, что было сделано, заключалось в том, чтобы использовать собственную функцию массивов, фильтровать и добавлять логику для каждой ее строки, и если эта логика выполняется, возвращать эту строку в окончательный массив, который я хочу.
Полный код:
// Input
let input = [
{ 'parent': 'A', 'child': 'RST', 'expense1': 1, 'expense2': 2, 'expense3': 3 },
{ 'parent': 'A', 'child': 'EST', 'expense1': 4 4, 'expense2': 5, 'expense3': 6 },
{ 'parent': 'A', 'child': 'QST', 'expense1': 4, 'expense2': 2, 'expense3': 6 },
{ 'parent': 'B', 'child': 'EST', 'expense1': 1, 'expense2': 2, 'expense3': -3 }
{ 'parent': 'B', 'child': 'VST', 'expense1': 6, 'expense2': 2, 'expense3': 3 },
{ 'parent': 'B', 'child': 'NST', 'expense1': 3, 'expense2': 8, 'expense3': 7 },
{ 'parent': 'C', 'child': 'UST', 'expense1': -8, 'expense2': -2, 'expense3': 3 },
{ 'parent': 'C', 'child': 'PST', 'expense1': -6, 'expense2': -5, 'expense3': -3 }
{ 'parent': 'C', 'child': 'LST', 'expense1': -3, 'expense2': -8, 'expense3': -7 }
{ 'parent': 'D', 'child': 'WST', 'expense1': -8, 'expense2': -2, 'expense3': -3 }
{ 'parent': 'D', 'child': 'CST', 'expense1': -6, 'expense2': -5, 'expense3': -3 }
{ 'parent': 'B', 'child': 'KST', 'expense1': -3, 'expense2': -8, 'expense3': -7 }
]
// Output
let output = [
{ 'parent': 'B', 'child': 'EST', 'expense1': 1, 'expense2': 2, 'expense3': -3 }
{ 'parent': 'B', 'child': 'VST', 'expense1': 6, 'expense2': 2, 'expense3': 3 },
{ 'parent': 'B', 'child': 'NST', 'expense1': 3, 'expense2': 8, 'expense3': 7 },
{ 'parent': 'C', 'child': 'UST', 'expense1': -8, 'expense2': -2, 'expense3': 3 },
{ 'parent': 'C', 'child': 'PST', 'expense1': -6, 'expense2': -5, 'expense3': -3 }
{ 'parent': 'C', 'child': 'LST', 'expense1': -3, 'expense2': -8, 'expense3': -7 },
]
const filterLogic = rowOfInput => {
if ( // Add logic to include or exclude line
(rowOfInput.expense1 < 0 && rowOfInput.expense2 < 0 && rowOfInput.expense3 < 0) ||
(rowOfInput.expense1 > 0 && rowOfInput.expense2 > 0 && rowOfInput.expense3 > 0)
) return rowOfInput // if is your desired, return that line
}
let inputFiltered = input.filter(filterLogic)
console.info(output)
console.info(inputFiltered)
Переведено с помощью www.DeepL.com/Translator (бесплатная версия)
Какой код вы уже пробовали? Почему это не сработало?