Javascript 超高效对象展开
我有一个来自Firebase的快照,我想把它转换成JS类。我现在有一个怪物循环,几乎在所有方面都很糟糕。有没有人能举一个更好的例子来将原始json转换成这个类 我目前的方法很长(见第二节)。我很想学习一种更快更有效的方法 类别:Javascript 超高效对象展开,javascript,json,Javascript,Json,我有一个来自Firebase的快照,我想把它转换成JS类。我现在有一个怪物循环,几乎在所有方面都很糟糕。有没有人能举一个更好的例子来将原始json转换成这个类 我目前的方法很长(见第二节)。我很想学习一种更快更有效的方法 类别: class SuggestedLocation { country_slug region_slug slug marker_type typeInType geometry properties type id construc
class SuggestedLocation {
country_slug
region_slug
slug
marker_type
typeInType
geometry
properties
type
id
constructor(country_slug, region_slug, slug, marker_type, typeInType, geometry, properties, type, id) {
this.country_slug = country_slug
this.region_slug = region_slug
this.slug = slug
this.marker_type = marker_type
this.typeInType = typeInType
this.geometry = geometry
this.properties = properties
this.type = type
this.id = id
}
}
当前展开方法:
static fromSnapshot(snapshot) {
let suggestedLocations = [new SuggestedLocation()]
if (snapshot.exists()) {
const value = snapshot.val()
const countrySlugs = Object.keys(value)
for (const country_slug of countrySlugs) {
const regionSlugs = Object.keys(value[country_slug])
for (const region_slug of regionSlugs) {
const slugs = Object.keys(value[country_slug][region_slug])
for (const slug of slugs) {
const markerTypes = Object.keys(value[country_slug][region_slug][slug])
for (const markerType of markerTypes) {
const accomAmenityTypes = Object.keys(value[country_slug][region_slug][slug][markerType])
for (const accomAmenityType in accomAmenityTypes) {
const typeInTypes = Object.keys(value[country_slug][region_slug][slug][markerType][accomAmenityType])
for (const typeInType of typeInTypes) {
const ids = Object.keys(value[country_slug][region_slug][slug][markerType][accomAmenityType][typeInType])
for (const id in ids) {
const geoJsonObject = value[country_slug][region_slug][slug][markerType][accomAmenityType][typeInType][id]
const properties = geoJsonObject["properties"]
const geometry = geoJsonObject["geometry"]
const type = geoJsonObject["type"]
suggestedLocations.push(new SuggestedLocation(country_slug, region_slug, slug, markerType, typeInType, geometry, properties, type, id))
}
}
}
}
}
}
}
}
return new SuggestedLocationsObject(suggestedLocations)
}
Json示例:
{
"united-kingdom" : {
"calderdale" : {
"rossendale-way" : {
"accommodations" : {
"Campground" : {
"zO3HxZVELbd" : {
"geometry" : {
"coordinates" : [ -2.1901328761018704, 53.65022995288969 ],
"type" : "Point"
},
"properties" : {
"marker-color" : "#6e875f",
"marker-size" : "medium",
"marker-symbol" : "lodging",
"name" : "",
"place_id" : "zO3HxZVELbd",
"plus_code" : ""
},
"type" : "Feature"
}
}
}
}
}
}
}
您必须以任何方式深入查看快照数据,但您可以使用
Object.entries
而不是Object.keys
,因此您可以一次性获得相应的值
此外,您还可以使用map
和flatMap
生成SuggestedLocation
实例数组,而无需显式push
如果对<代码>的多次赋值> .*/COD>打扰您,那么您可以考虑更改构造函数签名,以便它使用一个对象而不是单个值。然后可以使用
Object.assign
一次性传递这些值
最后,我真的不明白为什么希望SuggestedLocation
实例的数组有一个包含所有未定义属性的初始元素([new SuggestedLocation()]
)。我能想到的唯一原因是snapshot.exists()
为false的情况。。。然后您将有一个包含这一项的数组。但是当有数据时,为什么要包含这个虚拟条目呢
下面是表达上述思想的代码(使用纯JavaScript,而不是TypeScript):
class SuggestedLocationsObject扩展数组{
建造师(arr){
超级();
对象。分配(此,arr);
}
}
类建议位置{
建造师(obj){
分配(本,obj);
}
}
函数fromsapshot(快照){
返回新建议的位置对象(
!snapshot.exists()
?[新建议位置()]
:Object.entries(snapshot.val()).flatMap([country\u slug,regionslug])=>
Object.entries(regionSlugs).flatMap([region\u slug,slugs])=>
Object.entries(slug.flatMap)([slug,markerTypes])=>
Object.entries(markerTypes).flatMap([markerType,acomamenitytypes])=>
Object.entries(accomAmenityTypes).flatMap([accomAmenityType,typeInTypes])=>
Object.entries(typeInTypes).flatMap([typeInType,id])=>
Object.entries(id).map([id,{properties,geometry,type}])=>
新建议位置({country\u slug,region\u slug,slug,markerType,typeInType,geometry,properties,type,id})
)
)
)
)
)
)
)
);
}
让数据={
“联合王国”:{
“卡尔德代尔”:{
“罗森代尔之路”:{
“住宿”:{
“营地”:{
“zO3HxZVELbd”:{
“几何学”:{
“坐标”:[-2.1901328761018704,53.65022995288969],
“类型”:“点”
},
“财产”:{
“标记颜色”:“6e875f”,
“标记大小”:“中等”,
“标记符号”:“住宿”,
“名称”:“,
“地点id”:“zO3HxZVELbd”,
“加号代码”:”
},
“类型”:“特征”
}
}
}
}
}
}
};
让快照={
exists(){return true},
val(){返回数据}
}
让结果=来自快照(快照);
控制台日志(结果)代码>如果该快照具有未知数量的子对象,那么您将无法获得比这些循环更高的效率。如果每个快照都有1个SuggestedLocation
,则根本不需要循环。切圆相关(与可读性相关)我不明白为什么要获取对象属性并进行迭代,但仍然使用每个对象“内部”的完整“路径”当您已经直接处理相关对象时的属性。[new SuggestedLocation()]
的目的是什么?该实例的所有属性都将是未定义的…不,对于初始的空SuggestedLocation,这是一个公平点。这只是为了让我的生活更容易与内置的自动完成!