Javascript 使用Knockout JS删除数组中的重复名称

Javascript 使用Knockout JS删除数组中的重复名称,javascript,google-maps,knockout.js,Javascript,Google Maps,Knockout.js,我正试图找出如何使用knockoutjs删除googlemaps项目的重复名称。我有一个咖啡店的列表,几个连锁店的多个位置,我只希望名称显示一次。这是我的JS: function AppViewModel() { this.header = ko.observable("Wilmington Coffee Shops"); // List of coffee shops to select var self = this; self.shops = ko.observable

我正试图找出如何使用knockoutjs删除googlemaps项目的重复名称。我有一个咖啡店的列表,几个连锁店的多个位置,我只希望名称显示一次。这是我的JS:

function AppViewModel() {
  this.header = ko.observable("Wilmington Coffee Shops");

  // List of coffee shops to select
  var self = this; 
  self.shops = ko.observableArray([
    {title: 'Port City Java', location: {lat: 34.235912, lng: -77.948826}},
    {title: 'Port City Java', location: {lat: 34.238930, lng: -77.949028}},
    {title: 'Port City Java', location: {lat: 34.237872, lng: -77.921174}},
    {title: 'Port City Java', location: {lat: 34.201974, lng: -77.922590}},
    {title: 'Port City Java', location: {lat: 34.242096, lng: -77.863673}},
    {title: 'Port City Java', location: {lat: 34.194293, lng: -77.910822}},
    {title: 'Starbucks', location: {lat: 34.216803, lng: -77.906956}},
    {title: 'Starbucks', location: {lat: 34.242066, lng: -77.828570}},
    {title: 'Starbucks', location: {lat: 34.196443, lng: -77.890236}},
    {title: 'Folks on Fourth', location: {lat: 34.243700, lng: -77.945501}},
    {title: '24 South Coffee House', location: {lat: 34.234496, lng: -77.948725}},
    {title: 'Karen\'s Cafe', location: {lat: 34.238730, lng: -77.948981}},
    {title: 'Luna Caffè', location: {lat: 34.228263, lng: -77.940812}},
    {title: 'Folks Cafe', location: {lat: 34.237704, lng: -77.934188}},
    {title: 'Zola Coffee & Tea', location: {lat: 34.213228, lng: -77.887951}},
    {title: 'Grinders Caffè', location: {lat: 34.212560, lng: -77.871677}},
    {title: 'Daily Grind', location: {lat: 34.241911, lng: -77.867955}},
    {title: 'Addicted to the Bean', location: {lat: 34.213678, lng: -77.886954}},
    {title: 'Bitty & Beau\'s Coffee', location: {lat: 34.242041, lng: -77.877485}},
    {title: 'Lucky Joe Craft Coffee', location: {lat: 34.266057, lng: -77.837758}},
    {title: 'Java Dog Coffee House', location: {lat: 34.239104, lng: -77.949228}},
    {title: 'Morning Glory Coffeehouse', location: {lat: 34.225831, lng: -77.929120}},
    {title: 'Bespoke Coffee & Dry Goods', location: {lat: 34.236453, lng: -77.947403}},
    {title: 'Brick + Mortar Coffee and Supply', location: {lat: 34.247251, lng: -77.946280}}
  ]);

  this.google = ko.observable(false);
  this.createMarkers = ko.computed(function(){
    if (self.google()){
      console.log("Google maps has finished loading");
      for (var i = 0; i < self.shops().length; i++) {
        var position = self.shops()[i].location;
        var title = self.shops()[i].title;
        var marker = new google.maps.Marker({
          position: position,
          title: title,
          animation: google.maps.Animation.DROP,
          map: map,
          id: i
        })
        self.shops()[i].marker = marker;
        markers.push(marker)
       }
       console.log(self.shops());
    }
  });
以下是我如何将其附加到HTML中的:

<div>

            <ul data-bind="foreach: shops">
                <li>
                    <span data-bind="text: $data.title, click: $root.shopMarker"></span>
                </li>
            </ul>

        </div>

允许使用下划线吗?如果是的话

  this.distinctShops = ko.computed(function() {
   var uniques = _.map(_.groupBy(ko.toJS(self.shops),function(doc){
           return doc.title;
      }),function(grouped){
           return grouped[0];
       });
     return uniques;
  }, this);
}

这是一把小提琴

如果您可以更改shops数组的结构,那么您可以更改它并从一开始就根据标题对它们进行分组

它看起来或多或少会像这样

 [
   {
    title: 'Port City Java', 
    locations: [
      { position: { lat: 34.235912, lng: -77.948826 } },
      { position: { lat: 34.238930, lng: -77.949028 } }
      // other locations
    ]
  },
  {
    title: 'Starbucks', 
    locations: [
      { position: { lat: 34.216803, lng: -77.906956 } },
      { position: { lat: 34.242066, lng: -77.828570 } },
      // other locations
    ]
  }
  // other shops
]
我还注意到AppViewModel的CreateMarkets是一个计算属性,它不返回任何内容。如果装载完成,您只需要将属性标记添加到商店中。因此,您可以使用并执行以下操作,而不是使用computed:

function AppViewModel() {
  this.header = ko.observable("Wilmington Coffee Shops");

  // List of coffee shops to select
  var self = this; 
  self.shops = ko.observableArray([
    {
      title: 'Port City Java', 
      locations: [
        { position: { lat: 34.235912, lng: -77.948826 } },
        { position: { lat: 34.238930, lng: -77.949028 } }
        // other locations
      ]
    },
    {
      title: 'Starbucks', 
      locations: [
        { position: { lat: 34.216803, lng: -77.906956 } },
        { position: { lat: 34.242066, lng: -77.828570 } },
        // other locations
      ]
    }
    // other shops
  ]);
  this.google = ko.observable(false);
  this.google.subscribe(function(isLoadingFinished) {
    if (isLoadingFinished){
      console.log("Google maps has finished loading");
      for (var i = 0; i < self.shops().length; i++) {
        var shop = self.shops()[i];
        shop.locations.forEach(function(location){
          var marker = new google.maps.Marker({
            position: location.position,
            title: shop.title,
            animation: google.maps.Animation.DROP,
            map: map,
            id: i
          })
          // add a new property called marker to the location object
          location.marker = marker;
        });
      }
      console.log(self.shops());
    } 
  });

希望这能有所帮助。

您想改变Observarray的结构,例如显示一次“Port City Java”,然后将六个位置列为嵌套数组,还是只为每个咖啡馆显示一个标题和位置?我愿意接受最简单/最可靠的选项。我只是想确保每个标记在实现时都有一个适当的信息窗口,并且每个标记都正确地显示出来。我要让名字可以点击,所以当你点击星巴克的时候,只有星巴克的标记显示了你有没有包括下划线?有一种方法可以写出来,我就是想不出它的安全性,四处搜索,确保有一百万种不同的方法可以在javascript中获得不同的值。至于淘汰实用程序,这里有一个很好的页面,显示了一些好的工具@我很乐意帮忙;