JavaScript - 在对象数组中查找对象数组中的对象

时间:2017-07-04 10:17:22

标签: javascript arrays json object filter

我正在使用Vue,lodash等

{
  "street": {
    "id": "1",
    "streetName": "test",
    "buildings": [
      {
        "id": "1",
        "buildingName": "test"
      }
    ]
  }
}

我有类似的设置。这是一个单一的对象,我基本上有一个这样的数组。

我得到的只是building.id值。

通过它,我需要能够找到它所属的建筑物,并且没有任何直接的建筑物清单供我使用。

目前

我使用嵌套循环遍历每个站点,直到找到具有该ID的建筑物。我不知道我是否正确地做了,感觉不对。

for(var i = 0; i < streets.length; i++){
    for(var x = 0; x < streets[i].buildings.length;x++){
        if(streets[i].buildings[x].id == '2aec6bed-8cdd-4043-9041-3db4681c6d08'){   

        }
    }
}

任何提示?感谢。

4 个答案:

答案 0 :(得分:1)

您可以使用filtersome方法的组合,如下所示:

var result = streets.filter(function(s) {
  return s.street.buildings.some(function(b) {
    return b.id === searchedId;
  });
});
  • 如果已迭代.some()的任何true具有building,则使用buildings方法将返回searchedId
  • 使用.filter()会过滤streets数组,仅返回street对象some()上的buildings方法调用将返回true的对象换句话说,符合id等于searchedId的条件。

<强>演示:

&#13;
&#13;
var streets = [{
  "street": {
    "id": "1",
    "streetName": "test",
    "buildings": [{
      "id": "1",
      "buildingName": "test"
    }]
  }
}, {
  "street": {
    "id": "1",
    "streetName": "test",
    "buildings": [{
      "id": '2aec6bed-8cdd-4043-9041-3db4681c6d08',
      "buildingName": "test"
    }]
  }
}];
var searchedId = '2aec6bed-8cdd-4043-9041-3db4681c6d08';

var result = streets.filter(function(s) {
  return s.street.buildings.some(function(b) {
    return b.id === searchedId;
  });
});
console.log(result);
&#13;
&#13;
&#13;

答案 1 :(得分:0)

如果你试图通过buildingId获取所有街道上的所有建筑物,这可以解决问题:

streetsList.map(streetItem => streetItem.street.buildings.find(building => building.id === searchedBuildingId)).filter(v => v);

.filter(v => v)用于过滤掉虚假值,因为我们想要一个干净的结果。

如果街道中的多个建筑物可能只有一个id,那么请在示例中使用.some代替.find

答案 2 :(得分:0)

据推测,您有一个 streets 对象,其中包含 street 对象,例如:

var streets = [
  street :{ ...  },
  street :{ ...  },
  ...
];

所以你需要走进每条街道并遍布建筑物。 for 循环应该相当高效,因为它可以在找到建筑物后立即返回。我认为任何内置的循环方法都不会这样做。

OP中的代码无效,因为streets[i].buildings必须为streets[i].streets.buildingsif(streets[i].buildings[x].id必须为if(streets[i].street.buildings[x].id

下面是一个工作 for 循环版本,还有一个使用最新Array方法的版本,即使在非常小的数据集上也是如此。根据{{​​3}}, for 循环版本在Safari中快了大约100倍,在Firefox中快了10倍,在Chrome中快了50倍。

我还认为 for 循环代码更具可读性,因此可以维护。

var streets = [{
      "street": {
        "id": "1",
        "streetName": "test",
        "buildings": [{
          "id": "1",
          "buildingName": "test"
        }, {
          "id": "2",
          "buildingName": "test"
        }]
      }
    }, {
      "street": {
        "id": "2",
        "streetName": "test",
        "buildings": [{
          "id": "3",
          "buildingName": "test"
        }]
      }
    }
];

function getBldById(data, id) {
  for (var i=0, iLen=streets.length; i<iLen; i++) {
    var street = streets[i].street;

    for (var j=0, jLen=street.buildings.length; j<jLen; j++) {
      if (street.buildings[j].id == id) {
        return street.buildings[j];
      }    
    }
  }
  return null;
}

console.log(getBldById(streets, '1'));

function getBldById2(data, id) {
  return data.map(streetObj => 
    streetObj.street.buildings.find(building => 
      building.id === id)
    ).filter(v => v)[0];
}

console.log(getBldById2(streets, '1'));

答案 3 :(得分:-2)

你可能遗失了street财产,对吗? 我的意思是它应该是:streets[i].street.buildings[x].id