2014-02-12 2 views
-1

Скажем, я хочу, чтобы реализовать эту функцию:Как реализовать универсальную функцию отображения?

function myMapper(data, mapping) { } 

С входными существами:

data = { hello : 'hi' , embedded : { prop1 : 'hiiiii' } }; 

mapping = { hello : 'HELLO', 'embedded.prop1' : 'embedded.propOne' }; 

Выходом будет:

res = myMapper(data, mapping); 

res is { HELLO : 'hi' , embedded : { propOne : 'hiiiii' } }; 

Чтобы сделать это ясно:

  1. Составление сопоставления ле свойство: привет -> ПРИВЕТ
  2. Отображения вложенных свойств, с точкой в ​​качестве разделителя: embedded.prop1 -> embedded.propOne
  3. Старых свойств удаляются (привет и embedded.prop1)
  4. Это должно быть общим функция, принимающая любое комплексное отображение
  5. Не требуется для поддержки переименования контейнеров: embedded.prop1 -> EMBEDDED.prop1 is не.
  6. Значения свойств остаться, очевидно, то же самое
  7. Если свойство, указанное в отображении не найден, то оно установлено нулевое значение
  8. бонусных баллов за reverseMapper, который, принимая то же отображение, делает обратную операцию
+0

Я не могу представить себе использование для такой функции. Он пытается сделать слишком много вещей одновременно и, вероятно, даст вам неожиданные результаты чаще, чем правильные результаты. Несмотря на это, это довольно не по теме для переполнения стека. Вы только что отправили * длинный список требований и попросили нас сделать вашу работу за вас. – meagar

+1

Итак ... вы просите людей реализовать это для вас? Вы спрашиваете, хорошая ли это идея или нет? Вы просите людей ознакомиться и посмотреть, есть ли у этих требований какие-либо проблемы? – ajp15243

+0

Это был бы хороший каталон для начинающих http://www.codewars.com – aemxdp

ответ

3

Довольно тривиальный, на самом деле:

function myMapper(data, mapping, reverse) { 
    var res = {}; 
    for (var n in mapping) { 
     var from = (reverse ? mapping[n] : n).split("."), 
      to = (reverse ? n : mapping[n]).split("."); 
     for (var o=res, p=data, i=0; i<from.length-1; i++) { 
      o = o[to[i]] || (o[to[i]] = {}); 
      p = p && p[from[i]]; 
     } 
     o[to[i]] = p && p[from[i]] || null; 
    } 
    return res; 
} 
+0

Спасибо, выглядит интересно, я проверю это сейчас. – dangonfast

+0

Работает отлично. Небольшая ошибка во внутреннем цикле (p уже определена). И я забыл упомянуть: свойства, не указанные в отображении *, должны храниться как-есть *. Я попытаюсь добавить это сейчас. – dangonfast

+0

Да, вы должны были указать, что ... A 'для (n в данных), если (! (N в res || n при отображении)) res [n] = data [n ]; 'перед тем, как' return' должен сделать это (хотя и не работает в обратном случае). – Bergi

1

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

function myMapper(data, mapping) { 
    var key, mkey, ret = {}; 
    for (key in data) { 
     mkey = mapping[key]; 
     //check if there is a direct mapping 
     if (mkey !== undefined) { 
      ret[mkey] = data[key]; 
     } else if (/* check for dot in mkey */) { 
      //use similar construct as above but parse mkey 
      ret = // assign to the new key 
     } else if ... etc. 


    } 
    return ret; 
} 
+0

Не задание, просто проблема в моем приложении с небольшим временем для решения. Спасибо, но решение от @Bergi выглядит проще (и делает разбиение по точкам и наоборот!) – dangonfast

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