如何將物件鍵轉換為具有不同資料型別的陣列?Javascript map 函式不涵蓋物件資料型別值。
例子:
let obj = {
data1: 'test',
data2: boolean,
data3: {
test1: 'test',
test2: 'test'
}
}
預期輸出:
let arr = [
'data1',
'data2',
'data3.test1',
'data3.test2'
]
uj5u.com熱心網友回復:
const listPaths = (obj) => {
function rKeys(o, path) {
if (typeof o !== "object") return path;
return Object.keys(o).map((key) =>
rKeys(o[key], path ? [path, key].join(".") : key)
);
}
return rKeys(obj).toString().split(",").filter(Boolean);
}
const obj = {
data1: 'test',
data2: false,
data3: {
test1: 'test',
test2: 'test'
}
};
console.log(listPaths(obj));
uj5u.com熱心網友回復:
另一個可能的選擇是創建一個函式transform來獲取物件的條目(物件的陣列),如果ue 不是物件,則將[[key, val], ...]這些條目中的每一個映射到它,否則,如果值是物件,則可以在內部物件上再次呼叫該函式,這將再次回傳一個鍵陣列。然后,您可以使用此鍵陣列將當前鍵(保存物件)作為前綴添加到內部物件中的鍵:keyvaltransform.map()
const obj = {
data1: 'test',
data2: true,
data3: {
test1: 'test',
test2: {
example1: 0
},
test3: 'test'
}
};
const transform = (obj) => {
return Object.entries(obj).flatMap(([key, val]) =>
Object(val) === val ? transform(val).map(subKey => `${key}.${subKey}`) : key
);
}
console.log(transform(obj));
uj5u.com熱心網友回復:
這是一種達到深層屬性的遞回方法。如果某些事情很難理解,請隨時提出問題。
const isArray = hit => Array.isArray(hit)
const isObject = hit => !isArray(hit) && typeof hit === 'object'
const isNonIterable = hit => !isArray(hit) && !isObject(hit)
const toPath = (data, prefix = '') => {
const store = []
if (isArray(data)) {
if (prefix) {
store.push(prefix)
}
store.push(...toPath(data[0], `${prefix}[i]`))
return store
}
if (isObject(data)) {
if (prefix) {
store.push(prefix)
}
for (const key in data) {
const currData = data[key]
const currPrefix = prefix ? `${prefix}.${key}` : key
if (isNonIterable(currData)) {
store.push(currPrefix)
} else {
store.push(...toPath(currData, currPrefix))
}
}
return store
}
return store
}
const data = {
match: {
id: 720359,
play: '2021-12-20 00:30:00',
score: null,
status: 'Postponed'
},
league: {
id: 1115,
kor: '',
name: 'Norway: Blno'
},
home_team: {
id: 1610,
kor: '',
name: 'Tromso'
},
away_team: {
id: 1613,
kor: '',
name: 'Avangard Omsk'
},
game: {
id: 3,
kor: '??',
name: 'basketball'
},
match_games: [
{
type: {
id: 1,
div: 'odd',
kor: '?/?/?',
name: '3Way Result'
},
odds: {
odd: {
size: 1,
Home: 2.95,
deep: 1,
stop: 0,
gap: 1.45,
Draw: 13,
Away: 1.5
}
},
score: '[83,60]'
}
]
}
const paths = toPath(data)
console.log(paths)
// [
// '[i]',
// '[i].match',
// '[i].match.id',
// '[i].match.play',
// '[i].match.score',
// '[i].match.status',
// '[i].league',
// '[i].league.id',
// '[i].league.kor',
// '[i].league.name',
// '[i].home_team',
// '[i].home_team.id',
// '[i].home_team.kor',
// '[i].home_team.name',
// '[i].away_team',
// '[i].away_team.id',
// '[i].away_team.kor',
// '[i].away_team.name',
// '[i].game',
// '[i].game.id',
// '[i].game.kor',
// '[i].game.name',
// '[i].match_games',
// '[i].match_games[i]',
// '[i].match_games[i].type',
// '[i].match_games[i].type.id',
// '[i].match_games[i].type.div',
// '[i].match_games[i].type.kor',
// '[i].match_games[i].type.name',
// '[i].match_games[i].odds',
// '[i].match_games[i].odds.odd',
// '[i].match_games[i].odds.odd.size',
// '[i].match_games[i].odds.odd.Home',
// '[i].match_games[i].odds.odd.deep',
// '[i].match_games[i].odds.odd.stop',
// '[i].match_games[i].odds.odd.gap',
// '[i].match_games[i].odds.odd.Draw',
// '[i].match_games[i].odds.odd.Away',
// '[i].match_games[i].score'
// ]
此外,您可以通過稍微調整代碼來添加資料型別:
const isArray = hit => Array.isArray(hit)
const isObject = hit => !isArray(hit) && typeof hit === 'object'
const isNonIterable = hit => !isArray(hit) && !isObject(hit)
const isBoolean = hit => typeof hit === 'boolean'
const isNumber = hit => typeof hit === 'number' || (!isNaN(Number(hit)) && !isBoolean(hit))
const isString = hit => typeof hit === 'string'
const isDate = hit => new Date(hit).toString() !== 'Invalid Date'
const getType = payload => {
if (isArray(payload)) {
return 'array'
}
if (isObject(payload)) {
return 'object'
}
if (isNumber(payload)) {
return 'number'
}
if (isDate(payload)) {
return 'date'
}
if (isString(payload)) {
return 'string'
}
if (isBoolean(payload)) {
return 'boolean'
}
if (isBoolean(payload)) {
return 'boolean'
}
}
const toPath = (data, prefix = '') => {
const store = []
const storeData = (loggerPayload, loggerPrefix) => ({
path: loggerPrefix,
type: getType(loggerPayload)
})
if (isArray(data)) {
if (prefix) {
store.push(storeData(data, prefix))
}
store.push(...toPath(data[0], `${prefix}[i]`))
return store
}
if (isObject(data)) {
if (prefix) {
store.push(storeData(data, prefix))
}
for (const key in data) {
const currData = data[key]
const currPrefix = prefix ? `${prefix}.${key}` : key
isNonIterable(currData)
? store.push(storeData(currData, currPrefix))
: store.push(...toPath(currData, currPrefix))
}
return store
}
return store
}
const data = [
{
match: {
id: 720359,
play: '2021-12-20 00:30:00',
score: null,
status: 'Postponed'
},
league: {
id: 1115,
kor: '',
name: 'Norway: Blno'
},
home_team: {
id: 1610,
kor: '',
name: 'Tromso'
},
away_team: {
id: 1613,
kor: '',
name: 'Avangard Omsk'
},
game: {
id: 3,
kor: '??',
name: 'basketball'
},
match_games: [
{
type: {
id: 1,
div: 'odd',
kor: '?/?/?',
name: '3Way Result'
},
odds: {
odd: {
size: 1,
Home: 2.95,
deep: 1,
stop: 0,
gap: 1.45,
Draw: 13,
Away: 1.5
}
},
score: '[83,60]'
}
]
}
]
const paths = toPath(data)
console.log(paths)
// [
// {
// "path": "[i]",
// "type": "object"
// },
// {
// "path": "[i].match",
// "type": "object"
// },
// {
// "path": "[i].match.id",
// "type": "number"
// },
// {
// "path": "[i].match.play",
// "type": "date"
// },
// {
// "path": "[i].match.score",
// "type": "object"
// },
// {
// "path": "[i].match.status",
// "type": "string"
// },
// {
// "path": "[i].league",
// "type": "object"
// },
// {
// "path": "[i].league.id",
// "type": "number"
// },
// {
// "path": "[i].league.kor",
// "type": "number"
// },
// {
// "path": "[i].league.name",
// "type": "string"
// },
// {
// "path": "[i].home_team",
// "type": "object"
// },
// {
// "path": "[i].home_team.id",
// "type": "number"
// },
// {
// "path": "[i].home_team.kor",
// "type": "number"
// },
// {
// "path": "[i].home_team.name",
// "type": "string"
// },
// {
// "path": "[i].away_team",
// "type": "object"
// },
// {
// "path": "[i].away_team.id",
// "type": "number"
// },
// {
// "path": "[i].away_team.kor",
// "type": "number"
// },
// {
// "path": "[i].away_team.name",
// "type": "string"
// },
// {
// "path": "[i].game",
// "type": "object"
// },
// {
// "path": "[i].game.id",
// "type": "number"
// },
// {
// "path": "[i].game.kor",
// "type": "string"
// },
// {
// "path": "[i].game.name",
// "type": "string"
// },
// {
// "path": "[i].match_games",
// "type": "array"
// },
// {
// "path": "[i].match_games[i]",
// "type": "object"
// },
// {
// "path": "[i].match_games[i].type",
// "type": "object"
// },
// {
// "path": "[i].match_games[i].type.id",
// "type": "number"
// },
// {
// "path": "[i].match_games[i].type.div",
// "type": "string"
// },
// {
// "path": "[i].match_games[i].type.kor",
// "type": "string"
// },
// {
// "path": "[i].match_games[i].type.name",
// "type": "string"
// },
// {
// "path": "[i].match_games[i].odds",
// "type": "object"
// },
// {
// "path": "[i].match_games[i].odds.odd",
// "type": "object"
// },
// {
// "path": "[i].match_games[i].odds.odd.size",
// "type": "number"
// },
// {
// "path": "[i].match_games[i].odds.odd.Home",
// "type": "number"
// },
// {
// "path": "[i].match_games[i].odds.odd.deep",
// "type": "number"
// },
// {
// "path": "[i].match_games[i].odds.odd.stop",
// "type": "number"
// },
// {
// "path": "[i].match_games[i].odds.odd.gap",
// "type": "number"
// },
// {
// "path": "[i].match_games[i].odds.odd.Draw",
// "type": "number"
// },
// {
// "path": "[i].match_games[i].odds.odd.Away",
// "type": "number"
// },
// {
// "path": "[i].match_games[i].score",
// "type": "string"
// }
// ]
uj5u.com熱心網友回復:
我建議創建一個函式,比如getKeys()遞回遍歷物件,一旦命中每個葉子項,就會以“abc”的形式回傳鍵。
let obj = {
data1: 'test',
data2: true,
data3: {
test1: 'test',
test2: 'test'
}
}
function getKeys(obj, path = []) {
let keys = [];
// We've hit a 'leaf' in the object tree, return the path.
if (!obj || typeof(obj) !== 'object') return [ path.join('.') ];
// Call recursively for each child object...
for(let k in obj) {
keys = [...keys, ...getKeys(obj[k], [...path, k])];
}
return keys;
}
console.log(getKeys(obj))
.as-console-wrapper { max-height: 100% !important; top: 0; }
uj5u.com熱心網友回復:
創建一個遞回函式,該函式接受物件的條目,并使用Array.flatMap(). 將當前鍵連接到前一個鍵。如果當前值是一個物件,則再次呼叫該函式,并傳遞值和當前鍵。如果不回傳當前密鑰。
這適用于多層嵌套物件。
const listPaths = (obj, init) => Object.entries(obj)
.flatMap(([k, v]) => {
const key = init ? `${init}.${k}` : k
return typeof v === 'object' ? listPaths(v, key) : key
})
const obj = {
data1: 'test',
data2: false,
data3: {
test1: 'test',
test2: 'test',
data3: {
'sub-test1': 'sub-test',
'sub-test2': 'sub-test'
}
}
}
const result = listPaths(obj)
console.log(result)
uj5u.com熱心網友回復:
正如其他答案所提到的,在這種情況下可以使用遞回。
以下是另一個我覺得很容易理解的實作。它使用typeof、Array.Map和spread,并且可以處理任何層次結構深度。
function getKeys(obj) {
let keys = [];
for(const prop in obj){
if (typeof obj[prop] === "object" && !Array.isArray(obj[prop])) {
let subKeys = getKeys(obj[prop]);
subKeys = subKeys.map(ele => `${prop}.${ele}`);
keys = [...keys, ...subKeys];
} else {
keys = [...keys, prop];
}
}
return keys;
}
let ob = {
data1: 'test',
data2: true,
data3: {
test1: 'test',
test2: 'test',
data4: {
hello: 1
}
}
}
console.log(getKeys(ob));
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/411929.html
標籤:
