@dc65k

Как правильно преобразовать данные (массивы)?

Всем привет, у меня есть задача преобразовать данные.
Исходный массив:
const data = [
    {
        type: 'Question',
        data: {
            title: 'Question1 title',
            subTitle: 'Question1 subTitle'
        }
    },
    {
        type: 'Question',
        data: {
            title: 'Question2 title',
            subTitle: 'Question2 subTitle'
        }
    },
    {
        type: 'SectionHeader',
        data: {
            title: 'title1'
        }
    },
    {
        type: 'W',
        data: {
            title: 'W1 title',
            subTitle: 'W1 subTitle'
        },
        properties: {
            isExpanded: true
        }
    },
    {
        type: 'W',
        data: {
            title: 'W2 title',
            subTitle: 'W2 subTitle'
        }
    },
    {
        type: 'SectionHeader',
        data: {
            title: 'title2'
        }
    }
]


Ожидаемый результат:
[
    {
        type: 'SectionQuestion',
        children: [
            {
                data: {
                    title: 'title',
                    subTitle: 'subTitle'
                }
            },
            {
                data: {
                    title: 'title',
                    subTitle: 'subTitle'
                }
            }
        ]
    },
    {
        type: 'SectionHeader',
        data: {
            title: 'title1'
        }
    },
    {
        type: 'SectionW',
        children: [
            {
                data: {
                    title: 'W1 title',
                    subTitle: 'W1 subTitle'
                },
                properties: {
                    isExpanded: true
                }
            },
            {
                data: {
                    title: 'W2 title',
                    subTitle: 'W2 subTitle'
                }
            }
        ]
    },
    {
        type: 'SectionHeader',
        data: {
            title: 'title2'
        }
    }
]


Моё решение:
const arrType = ['Question', 'W']

function f(arr, arrType) {

    let res = []

    let isPush = true

    let widgetData = {
        type: '',
        children: []
    }

    arr.forEach(item => {

        let { type } = item

        if (arrType.includes(type)) {

            widgetData.type = `Section${type}`

            widgetData.children.push({
                data: item.data,
                properties: item.properties
            })

            if (isPush) {
                res.push(widgetData)
                isPush = false
            }

        } else {

            res.push(item)

            widgetData = {
                type: '',
                children: []
            }

            isPush = true

        }

    })

    return res

}

console.log(f(data, arrType))


Подскажите, пожалуйста, как на ваш взгляд оптимизировать решение, убежден, что мой вариант не лучший.
  • Вопрос задан
  • 93 просмотра
Решения вопроса 2
@dimoff66
Кратко о себе: Я есть
const transform = data => {
  const res = data.reduce((agg, item) => {
    item = {...item}
    if (agg[agg.length - 1]?.type !== item.type) 
      agg.push({ type: item.type, children: [] })
    
    agg[agg.length - 1].children.push((delete item.type, item))
    return agg
  })

  res.filter(v => !v.type.startsWith('Section')).forEach(v => {
    v.type = 'Section' + v.type
  })

  return res
}
Ответ написан
Комментировать
0xD34F
@0xD34F Куратор тега JavaScript
const newData = data
  .reduce((acc, { type, ...n }) => (
    (acc[acc.length - 1]?.[0] !== type) && acc.push([ type, [] ]),
    acc[acc.length - 1][1].push(n),
    acc
  ), [])
  .map(([ type, children ]) => children.length > 1
    ? { type: `Section${type}`, children }
    : { type, ...children[0] }
  );
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
SilenceOfWinter
@SilenceOfWinter
та еще зажигалка...
используй значения по умолчанию function f(arr, arrType = ['Question', 'W']) и проверяй типы аргументов или хотя бы их наличие: arrType = arrType || [];

если уж взялся писать модерновый js, то используй его по полной - создай класс widgetData с конструктором и геттерами/сеттерами свойств

вместо includes используй indexOf т.к. это этот метод не поддерживается ie
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы