从Javascript中的对象返回最大数字和关联名称
这是我的react应用程序- 我试图返回最高和最低纬度以及城市名称。我有它的工作,以返回纬度,但名称来了未定义。。。这很奇怪,因为在我的玩笑测试中,我的函数工作得很好。我正在使用React、Javascript和API加载和存储数据。。。我在这个函数中所做的是将所有纬度放入一个数组,然后执行Math.max,然后循环通过this.cities,查看对象中的哪个纬度与我们放入mostNorthLat的最高纬度匹配,然后获得与lat匹配的城市名称 这是带有纯函数的javascript文件:从Javascript中的对象返回最大数字和关联名称,javascript,reactjs,Javascript,Reactjs,这是我的react应用程序- 我试图返回最高和最低纬度以及城市名称。我有它的工作,以返回纬度,但名称来了未定义。。。这很奇怪,因为在我的玩笑测试中,我的函数工作得很好。我正在使用React、Javascript和API加载和存储数据。。。我在这个函数中所做的是将所有纬度放入一个数组,然后执行Math.max,然后循环通过this.cities,查看对象中的哪个纬度与我们放入mostNorthLat的最高纬度匹配,然后获得与lat匹配的城市名称 这是带有纯函数的javascript文件: //Lo
//Loads cities in API and injects it into this.cities
async loadCities() {
const data = await postData(url + "all");
//Create a dictionary of cities and keep track of the last key
const cities = {};
data.forEach(x => {
cities[x.key] = x;
this.lastKey = (x.key > this.lastKey) ? x.key : this.lastKey;
});
this.cities = cities;
}
//This is my add function I use for adding new cities to my API, which then React uses to create my cards for each object in my cities object in the API
async addOrUpdate(city) {
let theUrl;
if (city.key) {
theUrl = url + 'update'
} else {
theUrl = url + 'add'
this.lastKey++;
city.key = this.lastKey;
city.population = Number(city.population)
}
await postData(theUrl, city);
this.cities[city.key] = city;
}
//My functions that are running the most North and most South
getMostNorthern() {
let latitudeArray = []
let theName;
for (let key in this.cities) {
latitudeArray.push(this.cities[key].latitude)
}
let mostNorthLat = Math.max.apply(null, latitudeArray);
for (let key in this.cities) {
if (mostNorthLat === this.cities[key].latitude) {
theName = this.cities[key].name
}
}
if (this.length() > 0) {
return `${theName} at ${mostNorthLat}°`
}
}
getMostSouthern() {
let latitudeArray = []
let theName;
for (let key in this.cities) {
latitudeArray.push(this.cities[key].latitude)
}
let mostSouthLat = Math.min.apply(null, latitudeArray);
for (let key in this.cities) {
if (mostSouthLat === this.cities[key].latitude) {
theName = this.cities[key].name
}
}
if (this.length() > 0) {
return `${theName} at ${mostSouthLat}°`
}
}
以下是城市对象的外观:
{
"key": 1,
"latitude": "1",
"longitude": "1",
"name": "City",
"population": 49500
},
每个城市对象都保存在一个称为“城市”的主要对象中
constructor() {
this.cities = {};
this.lastKey = 0;
}
这是一个物体内部3个城市的样子:
{
'1': City {
name: "Gangster's Paradise",
latitude: -15,
longitude: 5,
population: 10,
key: 1
},
'2': City {
name: 'Pho City',
latitude: 5,
longitude: 52,
population: 1050,
key: 2
},
'3': City {
name: 'Frisbee Land',
latitude: 0,
longitude: 12,
population: 1000000,
key: 3
}
}
我的反应部分:
function CitiesApp() {
const classes = useStyles();
const [message, setMessage] = useState('')
const [count, setCount] = useState(0)
const [total, setTotal] = useState()
const [northest, setNorthest] = useState()
const [southest, setSouthest] = useState()
useEffect(() => {
//Load cities from the API - re-render when count is updated
async function fetchData() {
try {
await cityCtrl.loadCities()
updateSummary()
} catch (e) {
userMsg('Turn on the server')
}
}
fetchData();
}, [count]);
async function onSave(city) {
await cityCtrl.addOrUpdate(city)
setCount(count + 1)
updateSummary()
}
async function deleteCard(thekey) {
await cityCtrl.deleteCard(thekey)
setCount(count + 1)
updateSummary()
}
async function moveIn(thekey, num) {
await cityCtrl.movedIn(thekey, num)
setCount(count + 1)
updateSummary()
}
async function moveOut(thekey, num) {
await cityCtrl.movedOut(thekey, num)
setCount(count + 1)
updateSummary()
}
function updateSummary() {
setTotal(cityCtrl.getTotalPopulation())
setNorthest(cityCtrl.getMostNorthern())
setSouthest(cityCtrl.getMostSouthern())
}
}
我认为你可以通过
将所有工作放在一个循环中简化。cities
:
getMostNorthern() {
if (!this.cities.length) return '';
let mostNorthernCity;
for (const key in this.cities) {
if (!mostNorthernCity) {
mostNorthernCity = this.cities[key];
continue;
}
if (this.cities[key].latitude > mostNorthernCity.latitude) {
mostNorthernCity = this.cities[key];
}
}
return `${mostNorthernCity.name} at ${mostNorthernCity.latitude}`;
}
getMostSouthern
的工作方式相同,但您可以将变量重命名为mostSouthernCity
,并使用小于比较器。我发现了问题!我的设置方式是在react中使用defaultValue,最初,任何新城市都有默认的“”空白值。然后在我提交表单后更改。。。然而,如果我输入一个数字,它将只是在字符串中,因此我必须将经度和纬度转换为一个数字,就像我对人口所做的那样,然后我的函数工作
async addOrUpdate(city) {
let theUrl;
if (city.key) {
theUrl = url + 'update'
} else {
theUrl = url + 'add'
this.lastKey++;
city.key = this.lastKey;
city.population = Number(city.population)
city.latitude = Number(city.latitude)
city.longitude = Number(city.longitude)
}
await postData(theUrl, city);
this.cities[city.key] = city;
}
看来你找到答案了 这里有一种通过对值数组排序来查找最大值和最小值的替代方法 这种方法使用具有规则对象的函数方法,而不是具有类的面向对象方法。请注意,这需要对代码进行重构,因为您当前使用的是
City
对象实例
const cities={
'1': {
名字:“黑帮的天堂”,
纬度:-15,
经度:5度,
人口:10,
关键词:1
},
'2': {
名称:'凤凰城',
纬度:5,
经度:52,
人口:1050,
关键词:2
},
'3': {
名称:“飞盘之地”,
纬度:0,
经度:12,
人口:1000000,
关键词:3
}
}
//城市对象包含的静态定义关键点
常数cityKeys=[
“姓名”,
“纬度”,
“经度”,
"人口",,
“钥匙”
]
//将值数组转换回城市对象
const cityArrayToObject=(城市)=>城市。
减少(
(累加器、电流、电流索引)=>{
累加器[cityKeys[currentIndex]]=当前
回流蓄能器
}, {}
)
//按从最小到最大的纬度对阵列排序
//然后返回转换后的第一个和最后一个元素
//使用上面的函数返回到一个对象。
//城市的值数组在排序之前如下所示:
/*
[
[“匪徒天堂”,-15,5,10,1],
[“飞盘地”,0,12,1000000,3],
[‘凤凰城’,5、52、1050、2]
]
*/
const sortedCities=对象
//用城市的钥匙做一个阵列
.钥匙(城市)
//将该数组映射到每个键的新值数组
.map((值,索引)=>Object.values(城市[value]))
//然后按索引1中的纬度对数组进行排序
.sort((a,b)=>a[1]-b[1])
//取出最后一个项目(pop),它是最大的
const max=cityarytoobject(sortedCities.pop())
//取出最低的第一项(班次)
const minimate=cityarytoobject(sortedCities.shift())
log('最大:',最大,'最小:',最小)
哪些产出:
Largest: {
name: 'Pho City',
latitude: 5,
longitude: 52,
population: 1050,
key: 2
}
Smallest: {
name: "Gangster's Paradise",
latitude: -15,
longitude: 5,
population: 10,
key: 1
}
请注意,这并不能解释两个城市可能具有相同纬度的情况。这两个城市是什么样子?@awarrier99我更新了问题以显示这一点。城市,谢谢!你能把整个课程和其他相关的文件都包括进去吗?建立一个基本的复制和测试它似乎工作fine@awarrier99当然,我已经添加了我的异步函数谢谢!这看起来更干净,也有效。你能解释一下continue在这个函数中的作用吗?我以前从未用过它
continue
将跳过for
循环中的其余代码-因为我们不想将第一个城市与其自身进行比较,continue
将在this.cities
中跳过前面的下一个城市。非常感谢您在这方面对我进行深入的讨论,这真是太棒了!