根据 "path" 获取 Object 的值

Get value of Objet, according the "path"

早上好, 我有一个具有这种结构的对象:

{
  instituts: {
    default: 999,
    users: { default: 888, email: 777 },
    docs: undefined,
    exams: { price: 3 },
    empowermentTests: 2,
    sessionsHist: 3
  },
  exams: { default: 0 },
  countries: 1,
  levels: 1,
  roles: { default: 1 },
  sessions: 1,
  tests: 1,
  users: { default: 3 },
  options: undefined,
  skills: { default: undefined }
}

我有一个数组给出了像 ["instituts", "users"].

这样的路径

感谢这个路径数组,我想解析我的对象和 return 的值: instituts.users.default('default',因为路径“users”之后没有其他条目,用户类型是一个对象)

另一个例子:路径:['instituts', "users", "email"] 我想要的值是:instituts.users.email(不是'default',因为在对象结构中,电子邮件是一个整数,而不是一个对象)。

我希望我足够清楚。

我尝试了很多东西,但我迷失了 ES6 功能:“filter/reduce/map ...”

感谢您的帮助。

我的代码:

我收到 URL : 例如 /api/instituts/1/users/email 我的 express 中间件名为:isAuthorized.

我的具有权力的对象(用于赋予用户角色)被命名为:powerNeedByHttpMethod

“路径”是通过分割和过滤给出的 URL :

const paths = req.url.split('/').filter(e => e !== 'api' && !parseInt(e) && e !== '');

我试着按照这个板上的一个例子来做这个:

getPowerNeed(obj, paths) {
    if (!obj) return null;

    const partial = paths.shift(),
          filteredKeys = Object.keys(obj).filter(k => k.toLowerCase().includes(partial));
  
    if (!filteredKeys.length) return null; // no keys with the path found
    
    return filteredKeys.reduce((acc, key) => {
      if(!paths.length) return { ...acc, [key]: obj[key] }
      
      const nest = module.exports.getPowerNeed(obj[key], [...paths]) // filter another level
      return nest ? { ...acc, [key]: nest } : acc
    }, null)
}

认为这就是你要找的东西:

const getPath = ([p, ...ps]) => (o) =>
  p == undefined ? o : getPath (ps) (o && o[p])

const getPowerNeed = (path, obj, node = getPath (path) (obj)) =>
  Object (node) === node && 'default' in node ? node .default : node
  
const input = {instituts: {default: 999, users: {default: 888, email: 777}, docs: undefined, exams: {price: 3}, empowermentTests: 2, sessionsHist: 3}, exams: {default: 0}, countries: 1, levels: 1, roles: {default: 1}, sessions: 1, tests: 1, users: {default: 3}, options: undefined, skills: {default: undefined}}

console .log (getPowerNeed (['instituts', 'users'], input)) //=> 888
console .log (getPowerNeed (['instituts', 'users', 'email'], input)) //=> 777
console .log (getPowerNeed (['instituts'], input)) //=> 999
console .log (getPowerNeed (['instituts', 'exams', 'price'], input)) //=> 3

我假设如果未找到默认值,那么您希望 return 实际值(如果存在)。对该问题的另一种合理解读是,您想 return 文字字符串 'instituts.users.email'。如果有必要,那不会更难做到。

效用函数 getPath 采用一条路径,并且 return 是一个从对象到对象中该路径处的值的函数,如果存在,returning undefined是沿该路径的任何缺失节点。主要功能是 getPowerNeed,它包装了一些 default-检查 getPath.

的调用

我找到了其他解决方案:

const routes = ['options', 'arbo1', 'arbo2'];
const objPower = {
  instituts: {
    default: 999,
    users: { default: 888, email: 777 },
    docs: undefined,
    exams: { price: 3 },
    empowermentTests: 2,
    sessionsHist: 3
  },
  exams: { default: 0 },
  countries: 1,
  levels: 1,
  roles: { default: 1 },
  sessions: 1,
  tests: 1,
  users: { default: 3 },
  options: { 
   default: 19822,
    arbo1 : { 
        arbo2 : {
        arbo3: 3
        }}},
  skills: { default: undefined }
}



function getPower(objPower, entries, defaultPowerNeeded) {

    // On extrait le premier élément de la route et on le retire.
  const firstEntry = entries.shift();
    // Object.keys to list all properties in raw (the original data), then
  // Array.prototype.filter to select keys that are present in the allowed list, using
  // Array.prototype.includes to make sure they are present
  // Array.prototype.reduce to build a new object with only the allowed properties.
  const filtered = Object.keys(objPower)
  .filter(key => key === firstEntry)
  .reduce((obj, key) => {
    obj[key] = objPower[key];
    if(objPower[key].default) {
        defaultPowerNeeded = objPower[key].default;
    }
    return obj;
  }, {})[firstEntry];
  
  if(!entries.length) {
    if(typeof filtered === 'object') {
        if(filtered.default) {
        return filtered.default;
      }
      else {
       return defaultPowerNeeded;
      }
     
    }
    else return filtered;
  }
  return getPower(filtered,entries, defaultPowerNeeded);
}


const defaultPowerNeeded = 12;
const result = getPower(objPower, routes, defaultPowerNeeded);
console.log(result);