Как отфильтровать нормализованные вложенные данные JSON без массива?

1

после использования библиотеки 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?

Любая помощь приветствуется! Спасибо

Теги:
redux
normalizr

1 ответ

0

Если вы не хотите использовать 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>
  • 0
    Ценю твою помощь. Я попробовал это, и я думаю, что это работает без ссылки status / is_live по 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) Может быть, есть более элегантный способ сделать это?
  • 0
    Проверьте обновленный ответ

Ещё вопросы

Сообщество Overcoder
Наверх
Меню