基于Javascript中for循环中生成的值筛选对象

基于Javascript中for循环中生成的值筛选对象,javascript,for-loop,filter,javascript-objects,Javascript,For Loop,Filter,Javascript Objects,我正在创建一个Javascript应用程序(没有第三方框架或库),它需要从JSON对象获取位置列表,并仅显示给定半径内的位置。我已经知道了如何确定一个位置的坐标是否在所需的半径内,但我不知道如何使用这些结果过滤对象。以下是相关代码: function filterObj(obj) { var radiusSize = 100; return function filter() { var result; for (var i in obj) {

我正在创建一个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);
}

使用承诺并对数据结构做出一些假设(结果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));
函数getFilteredLocations(纬度、经度、半径){
常量距离=项目=>
Math.pow(Math.abs(item.lat-lat),2)
+数学功率(数学abs(item.lon-lon),2);
const r=Math.pow(radius,2);//而不是在本例中执行sqrt
返回fetch('/api/locations.json')
.那么(
response=>response.json(),
error=>Promise.reject({消息:“获取资源失败”,错误}))
.那么(
arr=>arr.filter(item=>distance(item)Promise.reject({message:'Failed to parse JSON',error}));
}
getFilteredLocations(51.5073,-0.12755,0.009)//~伦敦查林十字街1公里半径
.然后(显示位置)
.catch(error=>console.error(error.message,error.error));

我还大大简化了GPS到毕达哥拉斯的距离,例如,您需要使用您的逻辑将coodinates属性转换为所需的值您的
filterObject
函数(返回一个过滤函数)不应将
obj
作为参数,因为这违背了这种currying函数的目的:即
obj
将以任何方式逐个元素传递给返回的函数,因此不需要在此处传递它

而是利用这个机会传递所需的半径。然后返回的函数将处理该半径

其次,返回的函数将获得一个元素值作为参数:您需要添加该参数并仅使用该值:在整个对象上不应有循环:这就是
。filter
稍后将要做的

因此它可以这样工作(为了清晰起见,我重命名了函数):

函数接近(半径=100){
返回函数过滤器(obj){
var lat=41.8781;
var-lon=87.6298;
变量坐标=(对象位置[0]。坐标)。拆分(“,”;
var lat2=编号(坐标[0]);
var lon2=编号(坐标[1]);

var结果=toRadius(getDistance(lat、lon、lat2、lon2))我认为你让这变得有点困难。请发布你返回的数据的结构,我认为我们能够帮助代码以更干净的方式工作。lat、lon、lat2、lon2的
来自哪里?就像你现在的代码一样,它们是未定义的。如果
JSON.parse(xml.responseText)的值
是您所期望的,那么
getObj
就不相关了here@ChristopherMesser我不会感到惊讶。我已经在我的帖子中添加了我的对象的一个示例。@trincot对此表示抱歉。我已经编辑了帖子并将它们添加回了。
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));
function nearerThan(radiusSize = 100) {
    return function filter(obj) {
        var lat = 41.8781;
        var lon = 87.6298;
        var coordinates = (obj.location.[0].coordinates).split(",");
        var lat2 = Number(coordinates[0]);
        var lon2 = Number(coordinates[1]);
        var result = toRadius(getDistance(lat, lon, lat2, lon2)) <= radiusSize;
        return result;
    };
}

function getObj() {
    var xml = new XMLHttpRequest();
    var nearerThan100 = nearerThan(100);

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

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