Как преобразовать ключи объекта во вложенные объекты - PullRequest
0 голосов
/ 05 января 2019

У меня есть этот объект:

const sampleObj = { 
  home: true,
  products_edit: true,
  products_create: true,
  orders_delete: true,
  pages_category_create: true
}

Я хочу преобразовать вышеуказанный объект в:

const result = {
    home: {
    status: 'full'
  },
  products: {
    status: 'limited',
    subOptions: {
      edit: true,
      create: true
    }
  },
  orders: {
    status: 'limited',
    subOptions: {
      delete: true,
    }
  },
  pages: {
    status: 'limited',
    subOptions: {
      category: {
        status: 'limited',
        subOptions: {
          create: true,
        }
      },
    }
  }
}

Итак, я хочу преобразовать ключи объекта во вложенные объекты на основе символа _, а число _ может быть больше 3.

Если ключ состоит из одной части, такой как «Домой», статус должен быть «полный», в противном случае он должен быть «ограниченным».

Это мой текущий код:

function rolesFlattener(obj) {
  let final = {};
  Object.keys(obj).forEach((item, index) => {
    const path = item.split('_');
    if(path.length > 1) {
      path.reduce((prev, current, i, array) => {
        if(!final[prev]) {
          final[prev] = {
            status: 'limited',
            subOptions: {}
          }
        }
        final[prev].subOptions[current] = true;

      return current;
      });
    }
    else {
      final[path[0]] = {
        status: 'full'
      } 
    }
  })
  console.log(final)
}

// userRole: {
  //   home: {
  //     status: 'full'
  //   },
  //   products: {
  //     status: 'limited',
  //     subOptions: {
  //       edit: true,
  //       create: true
  //     }
  //   },
  //   orders: {
  //     status: 'limited',
  //     subOptions: {
  //       delete: true,
  //     }
  //   },
  //   pages: {
  //     status: 'limited',
  //     subOptions: {
  //       category: {
  //         status: 'limited',
  //         subOptions: {
  //           create: true,
  //         }
  //       },
  //     }
  //   }
  // }

let sampleObj = { 
  home: true,
  products_edit: true,
  products_create: true,
  orders_delete: true,
  pages_category_create: true
}

rolesFlattener(sampleObj)

Ответы [ 2 ]

0 голосов
/ 05 января 2019

Вы можете взять пустой путь в качестве особого случая, принять { status: 'full' } в качестве нового значения.

Затем уменьшите ключи и назначьте новый объект по умолчанию, если он не существует, и верните subOptions для каждого цикла.

Наконец, присвойте значение.

function setValue(object, path, value) {
    var last = path.pop();

    if (!path.length) {
        value = { status: 'full' };
    }

    path.reduce(
        (o, k) => (o[k] = o[k] || { status: 'limited', subOptions: {} }).subOptions,
        object
    )[last] = value;
}

const
    values = { home: true, financials: true, products_edit: true, products_create: true, orders_delete: true, pages_category_create: true },
    result = {};

Object.entries(values).forEach(([k, v]) => setValue(result, k.split('_'), v));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
0 голосов
/ 05 января 2019

Вот как бы я это сделал, наверное, можно было бы оптимизировать.

Сочетание Object.keys и Array # Reduce.

const sampleObj = { 
  home: true,
  products_edit: true,
  products_create: true,
  orders_delete: true,
  pages_category_create: true
}

const res = Object.keys(sampleObj).reduce((acc,cur)=>{
  const value = sampleObj[cur];
  const tree  = cur.split("_");
  const root  = tree.shift();
  
  if(!acc[root]){
    acc[root] = {};
    if(tree.length === 0){
       acc[root].status = "full"
       return acc;
    } else {
       acc[root].subOptions = {};
       acc[root].status = "limited";
    }
  }
  
  acc[root].subOptions[tree.shift()] = tree.reverse().reduce((acc,cur)=>{
      return {[cur]:acc}
  }, value);
  return acc;
  
}, {});

console.log(res);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...