gpt4 book ai didi

javascript - 使用通用键重构对象/数组

转载 作者:行者123 更新时间:2023-12-05 03:17:09 24 4
gpt4 key购买 nike

我正在构建一个工具,允许用户从通用源(具有通用结构)获取数据并重新映射属性以匹配我的 API。

  1. 用户将输入源 URL(REST API 或 JSON);
  2. 用户将输入基于 JSON 的 DTO 指令

DTO 将是这样的 JSON:

{
"data.collection.name": "section.title",
"just.an.example": "data.foo",
}

当源提供具有这种结构的数据时:

{
"data": {
"foo": "bar",
"collection": {
"totalCount": 123,
"title": "Best sellers",
}
}
}

该功能会将值重新映射到:

{
"section": {
"title": "Best sellers"
},
"just": {
"an": {
"example": "bar"
}
}
}

我可以使用 lodash getset 方法实现这一点,算法如下:

const data = {
foo: "bar",
collection: {
title: "BestSellers",
},
just: {
an: {
example: "bar",
},
},
nodes: {
edges: [
{
title: "Orange juice",
slug: "orange-juice",
},
{
title: "Apple juice",
slug: "apple-juice",
},
],
},
};

let transformed = {};

const transformer = {
"collection.title": "section.title",
"just.an.example": "foo",
};

Object.keys(transformer).forEach((key) => {
const value = _.get(data, key);
const path = transformer[key];

_.set(transformed, path, value);
});

console.log(transformed);

现在我需要获得相同的结果,但需要使用数组属性(如 nodes.edges)。

用户 DTO JSON 看起来像这样(不是必需的,但很理想):

{
"data.collection.name": "section.title",
"nodes.edges.title": "products.title",
"nodes.edges.slug": "products.seo.slug",
}

将生成此输出:

{
"section": {
"title": "BestSellers"
},
"products": [
{
"title": "Orange Juice",
"seo": {
"slug": "orange-juice"
}
},
{
"title": "Apple Juice",
"seo": {
"slug": "apple-juice"
}
}
]
}

最佳答案

对于源数组的位置没有歧义,但对于目标数组的确切位置存在歧义。因此[]放在目标映射中,表示数组位置。

const data = { foo: "bar", collection: { title: "BestSellers", }, just: { an: { example: "bar", }, }, nodes: { edges: [ { title: "Orange juice", slug: "orange-juice", }, { title: "Without a slug" }, { slug: "without-a-title" }, { title: "Apple juice", slug: "apple-juice", }, ], }, };
const transformer = {
"collection.title": "section.title",
"nodes.edges.title": "products.items[].title",
"nodes.edges.slug": "products.items[].seo.slug",
};

function getAtPath(path, data) {
let s = path.split('.');
let v = data[s[0]];
if(s.length===1) return v;
let q = s.slice(1).join('.');
return Array.isArray(v) ? v.map(i=>getAtPath(q, i)) : getAtPath(q, v);
}
function setAtPath(path, value, dest) {
let s = path.split('.'), d = dest;
for(let [i,e] of s.entries()) {
if(i === s.length-1) d[e] = value;
else {
if(e.endsWith('[]')) {
e = e.substring(0, e.length-2);
value.forEach((j,k) => setAtPath(`${k}.${s.slice(i+1).join('.')}`, j, d[e]??=[]));
break;
}
else d = d[e]??={};
}
}
}
function transform(transformer, data) {
let r = {};
Object.entries(transformer).forEach(([x,y])=>setAtPath(y,getAtPath(x, data),r));
return r;
}
console.log(transform(transformer, data));

关于javascript - 使用通用键重构对象/数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74256072/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com