【问题标题】:Is there a better way to look up attributes in an array of arrays?有没有更好的方法来查找数组数组中的属性?
【发布时间】:2020-05-26 20:26:00
【问题描述】:

我有一个带有 switch 语句的函数,它查找单个 case,如果找不到,则运行 default,这是另一个 switch 语句。它基本上是通过我的整个数组进行查找。我确定有更好的方法来做到这一点我只是 javascript 的新手并且不知道。这是一个sn-p:

for(var i=0; i < parks.length; i++) {
    switch (parks[i][6]) {            
        case 'wc' : 
            wc.push(L.marker([parks[i][1], parks[i][2]], {icon: parks[i][4]}).bindpopup("<a href='" + parks[i][3] + "'>" + parks[i][0] + "</a>"));
            break;        
        default :
            switch (parks[i][7]) {            
         case 'grill' : 
            grill.push(L.marker([parks[i][1], parks[i][2]], {icon: parks[i][4]}).bindpopup("<a href='" + parks[i][3] + "'>" + parks[i][0] + "</a>"));
            break;        
         default :
            break;
            break;
    }
}

我的 parks 数组的一个例子,因为每个人都在问:

var parks = [
['Spårvagnsparken',59.3298868,18.0031605,'http://leksplay.com/sparvagnsparken', greenIcon, wc, grill, null, null, fence, null, null, null, null],
['Fredhällsparkens plaskdamm',  59.3320485,18.0029481, 'http://leksplay.com/fredhallsparkensplaskdamm', greenIcon, wc, null, null, null, null, null, null, water, null],
['Uggleparken',     59.3343715,18.0040208,'http://leksply.com/uggleparken', greenIcon, wc, null, null, null, null, pfence, null, null, null],
['Observatorielundens Parklek', 59.3413877,18.056007, 'http://leksplay.com/observatorielundensparklek', greenIcon, wc, null, null, null, null, pfence, null, null, toddler],

【问题讨论】:

  • 请显示parks 的值是什么样子的。
  • 请添加parks的示例。
  • 如果能看到 parks 数组的示例会很酷 - 我觉得使用更多键来存储不同标签很奇怪...
  • 我编辑了一个公园@Roko的例子
  • 只是为了理解一些事情,假设一个位置有两个(或多个)props(即:“wc”和“grill”) - 你想在其中放置两个图标相同的 POI 位置?

标签: javascript leaflet gis openstreetmap


【解决方案1】:

鉴于您提供的数组,我会

  • bindPopup,不是bindpopup
  • 将amarkers构造为对象{}
  • 检索所有(非NULL) POI的“道具”(如"toddler""wc"等)
  • 迭代检索到的道具,将newMarker() 推入markers 对象。
const markers = {};
const newMarker = poi => L.marker([poi.lat, poi.lng], {icon: poi.icon})
                       .bindPopup(`<a href="${poi.url}">${poi.name}</a>`);

const parks = [
  ['Spårvagnsparken', 59.3298868, 18.0031605, 'http://leksplay.com/sparvagnsparken', "greenIcon", "wc", "grill", null, null, "pfence", null, null, null, null],
  ['Fredhällsparkens plaskdamm', 59.3320485, 18.0029481, 'http://leksplay.com/fredhallsparkensplaskdamm', "greenIcon", "wc", null, null, null, null, null, null, "water", null],
  ['Uggleparken', 59.3343715, 18.0040208, 'http://leksply.com/uggleparken', "greenIcon", "wc", null, null, null, null, "pfence", null, null, null],
  ['Observatorielundens Parklek', 59.3413877, 18.056007, 'http://leksplay.com/observatorielundensparklek', "greenIcon", "wc", null, null, null, null, "pfence", null, null, "toddler"],
];

parks.forEach(([name, lat, lng, url, icon, ...props]) => {
  props.filter(Boolean).forEach(prop => {
     if (!(prop in markers)) markers[prop] = []; // Prepare if not exists
     markers[prop].push(newMarker({name, lat, lng, url, icon}));
  });
})

console.log(markers);

示例(仅包含对象,用于演示):

const markers = {};
const newMarker = poi => poi;

const parks = [
  ['Spårvagnsparken', 59.3298868, 18.0031605, 'http://leksplay.com/sparvagnsparken', "greenIcon", "wc", "grill", null, null, "pfence", null, null, null, null],
  ['Fredhällsparkens plaskdamm', 59.3320485, 18.0029481, 'http://leksplay.com/fredhallsparkensplaskdamm', "greenIcon", "wc", null, null, null, null, null, null, "water", null],
  ['Uggleparken', 59.3343715, 18.0040208, 'http://leksply.com/uggleparken', "greenIcon", "wc", null, null, null, null, "pfence", null, null, null],
  ['Observatorielundens Parklek', 59.3413877, 18.056007, 'http://leksplay.com/observatorielundensparklek', "greenIcon", "wc", null, null, null, null, "pfence", null, null, "toddler"],
];

parks.forEach(([name, lat, lng, url, icon, ...props]) => {
  props.filter(Boolean).forEach(prop => {
     if (!(prop in markers)) markers[prop] = []; // Prepare if not exists
     markers[prop].push(newMarker({name, lat, lng, url, icon}));
  });
})

console.log(markers);

【讨论】:

  • 我一整天都在尝试这个并且不断收到这个错误:Uncaught TypeError: L.marker(...).bindpopup is not a function
  • @MichaelPerna 我从你那里复制了那个。您可以在第二个片段中看到逻辑是如何工作的。你得到的错误正是它所说的:bindpopup is not a function。所以也许你应该检查文档。可能是错字?
  • leafletjs.com/examples/custom-iconsbindPopup,而不是像您发布的 bindpopup。也修复了那个。
【解决方案2】:

创建一个调用并返回L.marker 的函数,当条件通过时,在每次迭代时将数组传递给它。只需使用=== 来检查索引处的项目是wc 还是grill

const makeMarker = park => L.marker([park[1], park[2]], { icon: park[4] })
  .bindpopup("<a href='" + park[3] + "'>" + park[0] + "</a>");
for (const park of parks) {
  if (park[6] === 'wc') {
    wc.push(makeMarker(park));
  } else if (park[7] === 'grill') {
    grill.push(makeMarker(park));
  }
}

理想情况下,修复您的输入结构,以便在 [6][7] 等位置有不同的值,而不是在其中有一个值数组,然后检查数组中的不同值并将标记添加到数组对象:

const categories = ['wc', 'grill', /* ... */];
const markers = Object.fromEntries(
  categories.map(cat => [cat, []])
);
for (const park of parks) {
  const marker = makeMarker(park);
  const cat = categories.find(cat => park[6].includes(cat));
  markers[cat].push(marker);
}

【讨论】:

  • 谢谢,如果我可以构建一堆 else if 吗?我的数组中有 9 个属性要检查。
  • 您是否还有 9 个不同的数组要推送到?如果是这种情况,您应该使用数组对象而不是 9 个单独的变量来使代码 DRY
  • 你有例子吗?
  • @MichaelPerna 你 200% 确定你有 park[6] park[7] 等吗?为什么两个标签 "wc""grill"whatever 不存储在同一个数组键下?
  • @MichaelPerna 你真的应该考虑重组数组,它​​的当前格式非常复杂。我会改用一组值:['wc', 'grill', 'water']
猜你喜欢
  • 2020-08-31
  • 1970-01-01
  • 1970-01-01
  • 2018-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多