2014-10-10 4 views
0

Я пытаюсь из-за отсутствия улучшенных терминов «zip» или «merge» json объектов, основанных на одном повторном элементе в каждом. Пример:underscore/lodash - объединить объекты с одинаковыми элементами

var obj = { 
    CATS:[ 
     { 
      id:123, 
      LIST:[ 
       {result1:CAT1}, 
       {result2:CAT2} 
      ] 
     }, 
     { 
      id:987, 
      LIST:[ 
       {result1:CAT3}, 
       {result2:CAT4} 
      ] 
     } 
    ], 
    DOGS:[ 
     { 
      id:123, 
      LIST:[ 
       {result1:DOG1}, 
       {result2:DOG2} 
      ] 
     }, 
     { 
      id:987, 
      LIST:[ 
       {result1:DOG3}, 
       {result2:DOG4} 
      ] 
     } 
    ]  
} 

Я хотел бы использовать «идентификатор», вложенный в OBJ для создания:

var new_obj = { 
    123:[ 
     CATS:{ 
      LIST:[ 
       {result1:CAT1}, 
       {result2:CAT2}      
      ] 
     }, 
     DOGS:{ 
      LIST:[ 
       {result1:DOG1}, 
       {result2:DOG2}      
      ]    
     } 
    ], 
    987:[ 
     CATS:{ 
      LIST:[ 
       {result1:CAT3}, 
       {result2:CAT4}      
      ] 
     }, 
     DOGS:{ 
      LIST:[ 
       {result1:DOG3}, 
       {result2:DOG4}      
      ]    
     } 
    ]   
} 

Не неравнодушен к LoDash или Underscore ... счастливого использовать все работает. Спасибо!

** Caveat! Должен быть совместим с текстом. BLEH! **

+0

Ваш желаемый результат имеет неправильную структуру. Значение ключа '123' должно быть массивом, но оно заполняется парами ключ-значение. Вы имели в виду '123', чтобы быть объектом? –

ответ

1

Уф, после нескольких проб и ошибок, я, возможно, что вам нужно ...

var result = _.reduce(obj, function(memo, group, key) { 
    var ids = _.map(group, function(g) { 
    return g.id; 
    }); 

    _.each(ids, function(id) { 
    var obj = {}; 

    obj[key] = {}; 
    obj[key].LIST = _.filter(group, function(g) { 
     return g.id === id; 
    }).map(function(g) { 
     return g.LIST; 
    })[0]; 

    memo[id] = (memo[id] || []); 

    memo[id].push(obj); 
    }); 

    return memo; 
}, {}); 

Проверьте это работает ... http://jsbin.com/gabako/1/edit

+1

Люди, у нас есть contend-ах! @ jcreamer898 год результат правильный ... но это лучший способ? +1 для вашего быстрого ответа. На вашем пути к галочке ... – bkbarton

2

Предполагая, что вы предназначены значение 123 ключ на выходе будет хэш, а не массив, а затем либо без подчеркивания или lodash:

Object.keys(obj).reduce(        // Reduce the keys in the input 
    function(result, animals) {       // by taking each key like DOGS 
    animals.forEach(         // and for each of its 
     function(animal) {        // elements (animal) 
     result[animal.id] = result[animal.id] || {}; // create an ID field in result 
     result[animal.id][animals] = animal.list;  // add animal's list of results 
     }); 
    return result;         // and pass result to next key 
    }, 
    {} 
); 

для IE8, используйте соответствующие polyfills. Или сделайте очевидную переписку, используя эквиваленты подчеркивания/lodash.

+0

Полюбите тот факт, что вы НЕ используете ни одну библиотеку ... но мне нужно, чтобы она была совместимой с ie8. Я верю, что .reduce() и .forEach() неприменимы. Извините, что не упоминал об этом раньше. – bkbarton

+1

Если вы еще не используете прокладки, вы должны быть. См. Https://github.com/es-shims/es5-shim. –

Смежные вопросы