2016-06-24 3 views
3

У меня есть следующий объект:Как написать функцию, которая встраивает свойства объекта

var ob = { 
    view: { 
     name: 'zpo', 
     params: { 
      taskId: 3, 
      zuka: 'v' 
     } 
    } 
} 

Мне нужно, чтобы этот объект в следующем виде:

{ 
    "view.name":"zpo", 
    "view.params.taskId":3, 
    "view.params.zuka":"v" 
} 

Я написал функцию, которая может сделайте это, но проблема в том, что для этого требуются внешние переменные, переданные ему. Вот эта функция:

function inline(o, result, container) { 
    for (var p in o) { 
     if (typeof o[p] === "object") { 
      inline(o[p], result.length > 0 ? result+'.'+p : p, container); 
     } else { 
      container[result + '.' + p] = o[p]; 
     } 
    } 
} 

var ob = { 
    view: { 
     name: 'zpo', 
     params: { 
      taskId: 3, 
      zuka: 'v' 
     } 
    } 
} 

var c = {}; 
var r = inline(ob, '', c); 

Есть ли способ, чтобы написать эту функцию, чтобы вернуть правильный результат без необходимости пройти result и container внешних переменными?

+0

Перед тем, как попытаться сделать что-то ненужное: зачем он нужен в этом формате? Почему бы не просто использовать объект 'view' внутри' ob'? Что касается вашей проблемы с кодом: нет, это не так, просто возвращайте функцию, поместите этот 'container' в первую строку функций' container = {} ', а затем завершите функцию в' return container'. Основной шаблон возврата. –

+0

@ Mike'Pomax'Kamermans. можете ли вы привести пример того, что вы имеете в виду? –

ответ

0

Вот версия, которая не требует каких-либо параметров.

// Return an array containing the [key, value] couples of an object. 
 
const objEntries = o => Object.keys(o).map(k => [k, o[k]]); 
 

 
// Create an object from an array of [key, value] couples. 
 
const entriesObj = (entries, init={}) => entries.reduce((result, [key, val]) => { 
 
    result[key] = val; 
 
    return result; 
 
}, init); 
 

 
// Reduce on the object entries (as returned by objEntries) with an empty object as 
 
// initialiser. 
 
const inline = (o) => objEntries(o).reduce((result, [key, val]) => { 
 
    if(val instanceof Object){ 
 
    // If the value is an object, recursively inline it. 
 
    const inlineVal = inline(val); 
 
    // Prefix each property names of inlineVal with the key of val and add the 
 
    // properties to the result object. 
 
    entriesObj(
 
     objEntries(inlineVal).map(([subK, subVal]) => [key + '.' + subK, subVal]), 
 
     result 
 
    ); 
 
    } else { 
 
    // If val is not an object, just add it to the result as is. 
 
    result[key] = val; 
 
    } 
 
    // Return the result. 
 
    return result; 
 
}, {}); 
 

 
var ob = { 
 
    view: { 
 
     name: 'zpo', 
 
     params: { 
 
      taskId: 3, 
 
      zuka: 'v' 
 
     } 
 
    } 
 
} 
 

 
var r = inline(ob); 
 
console.log(r);

Я использовал функцию навигации и деструктурирующий. Старые браузеры не поддерживают его. Если вам нужно их поддерживать, просто замените функции стрелок на обычные функции и вручную разрушите аргументы.

+0

спасибо, не могли бы вы взглянуть на [мой другой вопрос] (http://stackoverflow.com/questions/37785593/improve-function-that-converts-serialized -ъект-в-точка-обозначение-в-js-объект) с соответствующей проблемой? –

+0

Извините, 0:45 в моей части света. Я сейчас отправляюсь спать. Я буду смотреть завтра, если у вас пока нет ответа. –

+0

Я пытаюсь выяснить, как работает ваша работа. Можете ли вы подробно рассказать о основных идеях, которые вы использовали? –

1

Если я понял вас правильно, вы хотите, чтобы вы не позвонили в свою inline() с помощью функции «empty» params.

Вы могли бы поймать этот случай в вашей функции непосредственно:

function inline(o, result, container) { 
    result = result || ''; 
    container = container || {}; 
    ... 
} 

var r = inline(ob); 

вы все еще должны были бы это Params для рекурсивной части вашей функции.

+1

dang такой же ответ –

0

javascript является удивительным!

function inline(o, result, container) { 
    result = result || ''; 
    container = container || {}; 
    for (var p in o) { 
    if (typeof o[p] === "object") { 
     inline(o[p], result.length > 0 ? result+'.'+p : p, container); 
    } else { 
     container[result + '.' + p] = o[p]; 
    } 
    } 
} 

var r = inline(ob); 
+0

13 секунд поздно, мой друг: D – lexith