상세 컨텐츠

본문 제목

Lodash 데이터 가공

lodash

by citykim 2023. 3. 19. 13:43

본문

map, reduce key: {value1, value2}를 배열로 변환하기

 

조건: Object key 안에 value 구조를 가진 데이터가 있다

목적: 해당 값을 배열로 변환

const tier = {
  BRONZE: {count: 545, price: 952}
  DIAMOND: {count: 870, price: 848}
  GOLD: {count: 176, price: 133}
  IRON: {count: 357, price: 175}
  MASTER: {count: 379, price: 95}
  Platinum: {count: 109, price: 439}
  SILVER: {count: 580, price: 563}
}

 

 

 

변환은 다음과 같이 한다 Array<{name: string, count: number, price: number}>

const result = _.map(tier, (value, key) => ({
                  tier: key,
                  count: value.count, price: value.price
              	}))

result = [
  {tier: 'BRONZE', count: 545, price: 952},
  {tier: 'DIAMOND', count: 870, price: 848},
  {tier: 'GOLD', count: 176, price: 133},
  {tier: 'IRON', count: 357, price: 175},
  {tier: 'MASTER', count: 379, price: 95},
  {tier: 'Platinum', count: 109, price: 439},
  {tier: 'SILVER', count: 580, price: 563},
]

위와 같이 변환할 수 있다

 

 

 

 

반대로 배열에서 Object로 변환하고싶다면

const object = _.reduce(result, (acc, cur) => {
  acc[cur.tier] = {price: cur.price}
  return acc
}, {})

object = {
  BRONZE: {price: 952}
  DIAMOND: {price: 848}
  GOLD: {price: 133}
  IRON: {price: 175}
  MASTER: {price: 95}
  Platinum: {price: 439}
  SILVER: {price: 563}
}

위와 같이 하면된다

 

 


groupby & sumby 특정값으로 데이터합치기

 

조건: Array<{date: string, count: number, price: number}> 의 데이터

목적: 특정값 기준으로 데이터를 합치고싶다

const sales = [
  { "date": "2023-02-02", "count": 301, "price": 698 },
  { "date": "2023-02-07", "count": 361, "price": 481 },
  { "date": "2023-02-06", "count": 887, "price": 319 },
  { "date": "2023-02-07", "count": 137, "price": 363 },
  { "date": "2023-02-01", "count": 127, "price": 701 },
  { "date": "2023-02-02", "count": 78, "price": 400 },
  { "date": "2023-02-07", "count": 922, "price": 55 },
  { "date": "2023-01-30", "count": 731, "price": 171 },
  { "date": "2023-02-08", "count": 317, "price": 48 },
  { "date": "2023-02-04", "count": 563, "price": 2 },
]

 

 

우선 Group by를 하면 처음 변환하려는 값과 같이 데이터가 변환된다

const result = _.groupBy(sales, 'date')

result = {
  "2023-02-02": [
    { "date": "2023-02-02", "count": 301, "price": 698 },
    { "date": "2023-02-02", "count": 78, "price": 400 }
  ],
  "2023-02-07": [
    { "date": "2023-02-07", "count": 361, "price": 481 },
    { "date": "2023-02-07", "count": 137, "price": 363 },
    { "date": "2023-02-07", "count": 922, "price": 55 }
  ],
  "2023-02-06": [
    { "date": "2023-02-06", "count": 887, "price": 319 }
  ],
  "2023-02-01": [
    { "date": "2023-02-01", "count": 127, "price": 701 }
  ],
  "2023-01-30": [
    { "date": "2023-01-30", "count": 731, "price": 171 }
  ],
  "2023-02-08": [
    { "date": "2023-02-08", "count": 317, "price": 48 }
  ],
  "2023-02-04": [
    { "date": "2023-02-04", "count": 563, "price": 2 }
  ]
}

 

 

그 이후는 groupby 결과값을 가지고 이전과 같은 데이터 변환과정을 거치면된다

const result = _.map(
    _.groupBy(sales, 'date'), (value, key) => (
    	({
          date: key,
          count: _.sumBy(value, 'count'),
          price: _.sumBy(value, 'price')
        })
    ))
  
// 또는

const data = _.groupBy(sales, 'date')
const result = _.map( data, (value, key) => (
    		({
              date: key,
              count: _.sumBy(value, 'count'),
              price: _.sumBy(value, 'price')
            })
          ))
        
result = [
  { "date": "2023-02-02", "count": 379, "price": 1098 },
  { "date": "2023-02-07", "count": 1420, "price": 899 },
  { "date": "2023-02-06", "count": 887, "price": 319 },
  { "date": "2023-02-01", "count": 127, "price": 701 },
  { "date": "2023-01-30", "count": 731, "price": 171 },
  { "date": "2023-02-08", "count": 317, "price": 48 },
  { "date": "2023-02-04", "count": 563, "price": 2 }
]

 

 

결과값을 정렬할 수도 있다

const result =
_.sortBy(
    _.map(
      _.groupBy(data, 'date'), (value, key) => ((
        {
             date: key,
             count: _.sumBy(value, 'count'),
             price: _.sumBy(value, 'price')
        }
      ))
	), 'date'
)
  
result = [
  { "date": "2023-01-30", "count": 731, "price": 171 },
  { "date": "2023-02-01", "count": 127, "price": 701 },
  { "date": "2023-02-02", "count": 379, "price": 1098 },
  { "date": "2023-02-04", "count": 563, "price": 2 },
  { "date": "2023-02-06", "count": 887, "price": 319 },
  { "date": "2023-02-07", "count": 1420, "price": 899 },
  { "date": "2023-02-08", "count": 317, "price": 48 }
]

 

 

 


filter

조건: Array<{tier: string, name: string, balance: number}> 구조를 가진 데이터가 있다

목적: 해당 값을 필터링

const users = [
  {tier: 'IRON', name: 'euismod', balance: 399},
  ...
  {tier:'IRON', name:'morbi', balance:132},
  {tier:'Platinum', name:'id', balance:428},
]

 

 

특정값 기준으로 데이터를 필터링한다

const result = _.filter(users, {tier: 'IRON'})
result = [
  {tier: 'IRON', name: 'euismod', balance: 399},
  {tier: 'IRON', name: 'sed', balance: 470},
  {tier: 'IRON', name: 'ultrices', balance: 766},
  {tier: 'IRON', name: 'aliquam', balance: 242},
  {tier: 'IRON', name: 'massa', balance: 179},
  {tier: 'IRON', name: 'tellus', balance: 365},
  {tier: 'IRON', name: 'vestibulum', balance: 629},
  {tier: 'IRON', name: 'tempor', balance: 667},
  {tier: 'IRON', name: 'morbi', balance: 132},
]

결과값은 위와같다

 

 

특정 값 기준으로 데이터를 나눈다

const result = {
  a: _.filter(users, x => x.tier == 'IRON' | x.tier == 'BRONZE' | x.tier == 'SILVER' | x.tier == 'GOLD' | x.tier == 'Platinum'),
  b: _.filter(users, x => x.tier == 'DIAMOND' | x.tier == 'MASTER'),
}

result = {
  a: [
    {tier: 'IRON', name: 'euismod', balance: 399}
    ...
    {tier: 'Platinum', name: 'sem', balance: 78}
  ],
  b: [
    {tier: 'DIAMOND', name: 'donec', balance: 361}
    ...
    {tier: 'MASTER', name: 'enim', balance: 520}
  ]
}

 

 

또는 map을 돌려서 값을 추가한 뒤 출력할 수 있다

const result = _.groupBy(
  _.map(users, (x) => {
    if (x.tier == 'IRON' | x.tier == 'BRONZE') x.level = 'low'
    if (x.tier == 'SILVER' | x.tier == 'GOLD') x.level = 'middle'
    if (x.tier == 'Platinum' | x.tier == 'DIAMOND' | x.tier == 'MASTER') x.level = 'high'
    return x
  }), 'level'
)

result = {
  high: [
    {tier: 'DIAMOND', name: 'donec', balance: 361, level: 'high'}
    ...
    {tier: 'Platinum', name: 'id', balance: 428, level: 'high'}
  ],
  low: [
    {tier: 'IRON', name: 'euismod', balance: 399, level: 'low'}
    ...
    {tier: 'BRONZE', name: 'tincidunt', balance: 862, level: 'low'}
  ],
  middle: [
    {tier: 'SILVER', name: 'laoreet', balance: 530, level: 'middle'}
    ...
    {tier: 'GOLD', name: 'ultricies', balance: 188, level: 'middle'}
  ]
}

 

 

 

댓글 영역