使用 Ramda 将点分隔的 key/value 对展开为嵌套对象

Unflatten a dot-separated key/value pair into a nested object using Ramda

Ramda 说明书解释了 here 如何将嵌套对象转换为点分隔的扁平化对象。 我是 Ramda 的新手,我想学习如何做与上述相反的事情。

它将转换这个对象:

{
  "company.name": "Name is required",
  "solarSystemInfo.name": "Name is required",
  "installer.business.name": "slkdfj is required"
}

到,

{
  "company": {
    "name": "Name is required"
  },
  "solarSystemInfo": {
    "name": "Name is required"
  },
  "installer": {
    "business": {
      "name": "slkdfj is requried"
    }
  }
}

使用纯 JS 的工作 fiddle 是 here

这可以通过使用 R.toPairs, then "unflattening" each pair into an object by splitting the key on each . into a list and passing that as the path to R.assocPath to build out the object. This will result in a list of objects that can then be merged together using R.mergeAll.

将对象拆分成对来实现

const data = {
  "company.name": "Name is required",
  "solarSystemInfo.name": "Name is required",
  "installer.business.name": "slkdfj is required"
}

const pathPairToObj = (key, val) =>
  R.assocPath(R.split('.', key), val, {})

const unflattenObj = R.pipe(
  R.toPairs,
  R.map(R.apply(pathPairToObj)),
  R.mergeAll
)

console.log(unflattenObj(data))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>

使用Reduce可以避免用多个键覆盖对象。

const data = {
    "company.name": "Name is required",
    "solarSystemInfo.name": "Name is required",
    "installer.business.name": "Reg. name is required",
    "installer.business.code": "NYSE code is required"
}
const buildObj = (acc,value) => {
    [key,val]=value;
    return R.assocPath(R.split('.', key), val, acc);
}

const unflattenObj = R.pipe(
    R.toPairs,
    R.reduce(buildObj,{})
);
console.log(unflattenObj(data));
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>

来自"Using Reduce you can avoid overwriting of objects with multiple keys."

如果您在 Typescript 项目上并且有 "Cannot find key" 或 "val"...您可以使用:

const data = {
    "company.name": "Name is required",
    "solarSystemInfo.name": "Name is required",
    "installer.business.name": "Reg. name is required",
    "installer.business.code": "NYSE code is required"
}

const buildObj = (acc, value) => {
  const [key,val] = value
  return R.assocPath(R.split('.', key), val, acc);
}

const unflattenObj = R.pipe(
  R.toPairs,
  R.reduce(buildObj,{})
)

console.log(unflattenObj(data))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>