我想動態列印物件鍵的路徑。這是我的代碼:
const Tree = ({ data }) => {
let path = "onboarding";
return Object.keys(data).map((key) => {
if (Array.isArray(data[key])) {
path = path "." key;
return (
<Tree data={data[key]}></Tree>
);
}
if (typeof data[key] === "object") {
path = path "." key;
return (
<Tree data={data[key]}></Tree>
);
} else {
path = path "." key;
return (
<input defaultValue={data[key]}
style={{ fontWeight: "bold" }}
disabled={!this.props.isEditable}/>
);
}
});
};
及其我的資料
onboarding: {
enumType: 1,
key: "key1",
steps: [
{
title: "STEP ONE",
description: "des1",
instructions: [
{
icon: "step_power",
label: {
text: "text1",
color: "A11111",
location: "top",
},
},
],
},
{
title: "STEP TWO",
description: "des2",
instructions: [
{
icon: "step_power",
label: {
text: "text2",
color: "A11111",
location: "top",
},
},
],
}
我想為每次迭代列印密鑰路徑,預期輸出:
- “列舉型別”
- “鑰匙”
- “腳步”
- “步驟[0]”
- “步驟[0].title”
- . . .
- “步驟[1].instructions[0].label.location”
uj5u.com熱心網友回復:
您必須將路徑作為道具傳遞,我制作了一個代碼框:https ://codesandbox.io/s/old-browser-crgd9r
編輯:在此處添加相關代碼作為評論建議
const Tree = ({ path, data }) => {
// We have 3 cases: Array, Object or neither
// If we have an array we want to cycle through the elements
// and keep track of the index
// If we have an object we want to cicle through the keys
// otherwise just return the value
if (Array.isArray(data)) {
return data.map((element, index) => {
let currentPath = `${path}[${index}]`;
return (
<Tree
path={currentPath}
data={element}
key={currentPath}
></Tree>
);
});
} else if (data instanceof Object) {
return Object.keys(data).map((key) => {
let currentPath = path !== "" ? `${path}.${key}` : key;
return <Tree data={data[key]} path={currentPath} key={currentPath} />;
});
} else {
return (
<div>
<label>{path}</label>
<input defaultValue={data} style={{ fontWeight: "bold" }} />
</div>
);
}
};
uj5u.com熱心網友回復:
另一種方法是將路徑提取代碼與 DOM 生成部分分開。這將使您可以使用更多可重用的功能。
以下是我可能以兩種不同的方式撰寫路徑提取部分的方法。首先作為您的輸出格式的多合一功能:
const stringPaths = (o, p = '') =>
Array .isArray (o)
? o .flatMap ((v, i) => [p, ...stringPaths (v, `${p}[${i}]`)]) .filter (Boolean)
: Object (o) === o
? [
p,
... Object .entries (o) .flatMap (([k, v]) => stringPaths (v, p ? `${p}.${k}` : k))
] .filter (Boolean)
: p
const onboarding = {enumType: 1, key: "key1", steps: [{title: "STEP ONE", description: "des1", instructions: [{icon: "step_power", label: {text: "text1", color: "A11111", location: "top"}}]}, {title: "STEP TWO", description: "des2", instructions: [{icon: "step_power", label: {text: "text2", color: "A11111", location: "top"}}]}]}
console .log (stringPaths (onboarding))
.as-console-wrapper {max-height: 100% !important; top: 0}
其次,以我喜歡的風格,生成更廣泛使用的中間格式 ( [["enumType"], ["key"], ["steps"], ["steps", 0], ["steps", 0, "title"], ..., ["steps", 1, "instructions", 0, "label", "location"]],然后將其轉換為您的目標格式:
const getPaths = (o) => Object (o) === o
? Object .entries (o)
.flatMap (([k, v], _, __, k1 = Array .isArray (o) ? Number (k) : k) =>
[[k1], ...getPaths (v) .map (p => [k1, ...p])]
)
: []
const stringPaths = (o) =>
getPaths (o) .map (
(path) => path .reduce ((p, n, i) => i == 0 ? n : Number .isInteger (n) ? `${p}[${n}]` : `${p}.${n}`, ``)
)
const onboarding = {enumType: 1, key: "key1", steps: [{title: "STEP ONE", description: "des1", instructions: [{icon: "step_power", label: {text: "text1", color: "A11111", location: "top"}}]}, {title: "STEP TWO", description: "des2", instructions: [{icon: "step_power", label: {text: "text2", color: "A11111", location: "top"}}]}]}
console .log (stringPaths (onboarding))
.as-console-wrapper {max-height: 100% !important; top: 0}
我認為這種細分使編碼更好。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/440054.html
標籤:javascript 反应 json 递归 寻找路径
下一篇:將回傳值分配給變數會中斷遞回
