简体   繁体   中英

coffeescript - manipulating json

this is just logic issue, if i have data:

    [
        {
            from: 'user a',
            to: 'user b'
        },
        {
            from: 'user a',
            to: 'user c'
        },
        {
            from: 'user b',
            to: 'user d'
        },
        {
            from: 'user c',
            to: 'user d'
        },
        {
            from: 'user c',
            to: 'user d'
        }
    ]

and i need to manipulating that data to:

    [
        {
            from: 'user a',
            to: ['user b', 'user c']
        },
        {
            from: 'user b',
            to: ['user d']
        },
        {
            from: 'user c',
            to: ['user d']
        }
    ]

i used this code:

    result = []
    objTemp = obj
    from = []       
    obj.map (o) ->
        if o.from not in from
            from.push o.from
            to = []
            objTemp.map (oo) ->
                if oo.from is o.from and oo.to not in to
                    to.push oo.to
            temp =
                from: o.from
                to: to
            result.push temp

but the result is not what i expected, there is still same 'to' in same 'from':

   [
        {
            from: 'user a',
            to: ['user b', 'user c']
        },
        {
            from: 'user b',
            to: ['user d']
        },
        {
            from: 'user c',
            to: ['user d', 'user d'] <-- the problem
        }
    ]

how do you guys resolve it using coffeescript?

Here is how I would do it:

res = []
obj.map (o) ->
  for r in res when r.from is o.from
    return (r.to.push o.to unless o.to in r.to)
  res.push from: o.from, to: [o.to]

for the convenience of having the groupBy and uniq methods (as well as chain , I guess), I'd probably use underscore or lowdash. if you're interested in the implementation of them in order to accomplish in raw coffeescript, you could look at the annotated source.

http://underscorejs.org/docs/underscore.html

chain / value just allows me to call these inline rather than making temp variables to hold them or make the function call less obvious.

fromUser = (x)-> x.from

toRelationships = (memo, items, index, list)->
  key = _(items).pluck('from')[0]
  vals = _.values(list[key])
  memo[key] = _(vals).chain().pluck('to').uniq().value()
  memo

result = _(data).chain().groupBy(fromUser).reduce(toRelationships, []).value()

# without chain
grouped = _(data).groupBy( fromUser )
result = _(grouped).reduce( toRelationships, [])

jsfiddle: http://jsfiddle.net/eaL6t1cn/2/

Here is my take, and I apologize now for this not being as succinct as I was hoping. This would have been a bit simplier if I used jQuery (or other third parties), but here it is without any libraries.

a =     [
        {
            from: 'user a',
            to: 'user b'
        },
        {
            from: 'user a',
            to: 'user c'
        },
        {
            from: 'user b',
            to: 'user d'
        },
        {
            from: 'user c',
            to: 'user d'
        },
        {
            from: 'user c',
            to: 'user d'
        }
    ]
c = {}
d = []
(value for value in a).forEach (v) -> 
     c[v.from] = do -> if not c[v.from] then [v.to] else ("#{c[v.from]},#{v.to}").
         split(',').reduce ((p,c) -> 
             if c not in p then p.concat([c]) else [c] ), [] 

d.push {'from':v,'to':k} for v,k of c

console.log d

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM