javascript - 根据 Javascript 中 for 循环中生成的值过滤对象

标签 javascript for-loop filter javascript-objects

我正在创建一个 Javascript 应用程序(没有第三方框架或库),它需要从 JSON 对象获取位置列表并仅显示给定半径内的那些位置。我已经弄清楚如何确定位置的坐标是否在所需的半径内,但我无法弄清楚如何使用这些结果来过滤对象。相关代码如下:

function filterObj(obj) {
    var radiusSize = 100;
    return function filter() {
        var result;
        for (var i in obj) {
            var lat = 41.8781;
            var lon = 87.6298;
            var coordinates = (obj[i].location.[0].coordinates).split(",");
            lat2 = Number(coordinates[0]);
            lon2 = Number(coordinates[1]);
            result = toRadius(getDistance(lat, lon, lat2, lon2)) <= radiusSize;
        }
        return result;
    };
}

function getObj() {
    var xml = new XMLHttpRequest();

    xml.onreadystatechange = function() {
        if (xml.readyState === XMLHttpRequest.DONE) {
            if (xml.readyState === 4 && xml.status === 200) {
                obj = JSON.parse(xml.responseText);
                var ObjFilter = filterObj(obj);
                var filtered = obj.filter(objFilter);
                displayLocations(filtered);
            } else {
              //code to handle errors
            }
        }
    };

    xml.open("GET", "/api/locations.json", true);
    xml.send(null);
}

现在,我知道由于 for 循环,filterObj() 会重复为“结果”返回“false”。我尝试将 filterObj() 的结果存储为数组,但随后“result”返回几个包含“toRadius(getDistance())”结果的数组,我再次知道这是因为 for 循环,但是将“结果”赋值移出循环会导致每个结果都为“假”,这是不正确的。

那么,在将对象传递给“displayLocations()”之前,如何使用“toRadius(getDistance())”在“filterObj()”中生成的结果来过滤在“getObj()”中获取的对象?

这是我正在使用的对象的示例:

[
  {
    "id": 12,
    "name": "Mount Helena City Park",
    "location": [
      {
        "city": "Helena, MT",
        "address": "Mount Helena City Park \nHelena, MT 59601",
        "coordinates": "46.5889179,-112.0593352"
      }
    ]
  }
]

最佳答案

使用 promise 并对数据结构做出一些假设(结果 JSON 解析为 [{lat: a, lon: b, ...}, {lat: c, lon: d, ...}, ...]),剩下的就是 .filter

function getFilteredLocations(lat, lon, radius) {
    const distance = item =>
        Math.pow(Math.abs(item.lat - lat), 2)
        + Math.pow(Math.abs(item.lon - lon), 2);
    const r = Math.pow(radius, 2); // rather than doing sqrts in this example

    return fetch('/api/locations.json')
        .then(
            response => response.json(),
            error => Promise.reject({message: 'Failed to fetch resource', error}))
        .then(
            arr => arr.filter(item => distance(item) <= r),
            error => Promise.reject({message: 'Failed to parse JSON', error}));
}

getFilteredLocations(51.5073, -0.12755, 0.009) // ~ 1km radius of Charing Cross, London
    .then(displayLocations)
    .catch(error => console.error(error.message, error.error));

对于距离示例,我还大大简化了 GPS 到毕达哥拉斯,您需要使用逻辑将您的坐标属性转换为所需的值

关于javascript - 根据 Javascript 中 for 循环中生成的值过滤对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45900423/

相关文章:

javascript 追加方法 anchor 链接在 jquery mobile 中不起作用

java - 如何在继续流式传输时获取第一个元素?

javascript - 过滤多个对象数组

haskell : Filtering a list of strings

javascript - 如何将html文件的控制台输出带入phantomjs

javascript - 如何在html中的img标签中添加 anchor 标签?

python - 使用 for 循环填充字典

java - 在 Java 中,一秒钟需要多长时间?测量 Java 中的延迟时间

JavaScript 如何从数组中获取所有字符串并使用过滤器打印它们?

javascript - 如何将 ngx-loading-bar 作为预加载器添加到 Angular 项目中