2014-10-27 2 views
0

это просто логика проблема, если у меня есть данные:CoffeeScript - манипулируя JSON

[ 
     { 
      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' 
     } 
    ] 

и мне нужно манипулировать эти данные:

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

я использовал этот код:

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 

но результат не тот, который я ожидал, есть все те же 'to' в том же '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 
     } 
    ] 

как вы, ребята, разрешаете его с помощью coffeescript?

ответ

0

Вот как я бы это сделать:

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] 
+0

Вы знаете, что используете неверную карту, когда вам нужно объявить массив вне функции карты. я могу предложить уменьшить? http://jsfiddle.net/eaL6t1cn/ –

+0

@JedSchneider, я считаю, что вы правы. Но у вашей скрипки есть небольшая проблема, она возвращает повторяющиеся записи. И если я попытаюсь «возвратиться» внутри цикла 'for', он выдает ошибку. Как вы справляетесь с этим? – mutil

+0

Извините @multi Я не отлаживал точность, просто показал вам, как передать массив, чтобы уменьшить использование вашего метода. я могу посмотреть на него немного глубже и дать ответ. Я не понимал, что это приводит к неточным результатам. –

0

для удобства имеющих groupBy и uniq методы (а также chain, я думаю), я бы, вероятно, использовать подчеркивание или lowdash. если вы заинтересованы в их реализации, чтобы выполнить в raw coffeescript, вы можете посмотреть на аннотированный источник.

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

chain/value просто позволяет мне называть эти инлайн вместо того, чтобы временные переменные, чтобы держать их или сделать вызов функции менее очевидной.

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/

0

Вот мое взятие, и я сейчас прошу прощения за это не столь же лаконично, как я надеялся. Это было бы немного проще, если бы я использовал jQuery (или другие третьи стороны), но здесь он не имеет библиотек.

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 
Смежные вопросы