Как отфильтровать нормализованные вложенные данные JSON без массива?
После использования normalizr
библиотека У меня есть следующий нормализованный объект JSON в состоянии Redux моего приложения:
{
sports: {
byId: {
1: {
id: 1,
name: 'Soccer',
slug: 'soccer'
},
2: {
id: 2,
name: 'Basketball',
slug: 'basketball'
},
3: {
id: 3,
name: 'American Football',
slug: 'american-football'
}
},
allIds: [
'1',
'2',
'3'
]
},
competitions: {
byId: {
'1': {
id: 1,
name: 'Competition 1',
short_name: 'Comp 1',
slug: 'comp-1',
sport: 1,
status: {
is_live: false
}
},
'2': {
id: 2,
name: 'Competition 2',
short_name: 'Comp 2',
slug: 'comp-2',
sport: 1,
status: {
is_live: true
}
},
'3': {
id: 3,
name: 'National Basketball League',
short_name: 'NBA',
slug: 'national-basketball-league',
sport_slug: 'basketball',
sport: 3,
status: {
is_live: true
}
}
},
allIds: [
'1',
'2',
'3'
]
}
Чего я хочу добиться: я хочу список competitions
фильтруется / классифицируется по sports
,
Как я могу это сделать?
Также я хочу иметь возможность группировать competitions
это status.is_live
,
Так как я могу получить список competitions
разбивка по sport
тот status.is_live
равна истине и competitions
status.is_live
равно ложь?
Любая помощь приветствуется! Спасибо
1 ответ
Если вы не хотите использовать lodash, вы можете написать .groupBy
функционировать довольно легко ( пример). Вам нужно будет перебрать выходной объект и переназначить его дочерние значения с помощью for вместо использования .mapValues
,
Я использовал lodash в примере, просто чтобы указать на логику.
Примечание. Я бы удалил группировку данных в исходном ответе и позволил бы клиенту сделать это самостоятельно - проще работать с несортированным массивом и фильтром / сопоставлением, которые вместо работы со значениями объекта с избыточным ключи (так как они представляют группы по идентификатору)
let data = {
sports: {
byId: {
1: {
id: 1,
name: 'Soccer',
slug: 'soccer'
},
2: {
id: 2,
name: 'Basketball',
slug: 'basketball'
},
3: {
id: 3,
name: 'American Football',
slug: 'american-football'
}
},
allIds: [
'1',
'2',
'3'
]
},
competitions: {
byId: {
'1': {
id: 1,
name: 'Competition 1',
short_name: 'Comp 1',
slug: 'comp-1',
sport: 1,
status: {
is_live: false
}
},
'2': {
id: 2,
name: 'Competition 2',
short_name: 'Comp 2',
slug: 'comp-2',
sport: 1,
status: {
is_live: true
}
},
'3': {
id: 3,
name: 'National Basketball League',
short_name: 'NBA',
slug: 'national-basketball-league',
sport_slug: 'basketball',
sport: 3,
status: {
is_live: true
}
}
},
allIds: [
'1',
'2',
'3'
]
}
}
let competitions = Object.values(data.competitions.byId)
// _.chain(arr) keeps returning `lodash` objects
// so I don't have to call it separately for every action
let filteredCompetitions = _.chain(competitions)
.groupBy(i => i.status.is_live)
.mapValues(i => _.groupBy(i, 'sport'))
.value() // returns the final value
console.log(filteredCompetitions)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>