после использования библиотеки 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
равен true, а status.is_live
competitions
равен false?
Любая помощь приветствуется! Спасибо
Если вы не хотите использовать lodash, вы можете легко написать функцию .groupBy
(пример). Вам нужно будет .mapValues
выходной объект и переназначить его дочерние значения с помощью a вместо использования .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>
sport
.let filteredCompetitions = _.chain(competitions) .groupBy('sport') .value() // returns the final value _.forEach(filteredCompetitions, function(value, key) { filteredCompetitions[key] = _.groupBy(filteredCompetitions[key], function(item) { return item.status.is_live; }); }); console.log(filteredCompetitions)
Может быть, есть более элегантный способ сделать это?