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

时间:2017-03-10 14:24:59

标签: javascript google-maps knockout.js

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

    //header
    $headers = "MIME-Version: 1.0\r\n";
    $headers .= "From:".$sender_email."\r\n";
    $headers .= "Reply-To: ".$sender_email."" . "\r\n";
    $headers .= "Content-Type: multipart/mixed; boundary = $boundary\r\n\r\n";

    //message text
    $body = "--$boundary\r\n";
    $body .= "Content-Type: text/plain; charset=ISO-8859-1\r\n";
    $body .= "Content-Transfer-Encoding: base64\r\n\r\n";
    $body .= chunk_split(base64_encode($message)); 

以下是我在HTML中添加的方法:

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());
    }
  });

2 个答案:

答案 0 :(得分:1)

你可以使用下划线吗?如果是的话

  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);
}

这是一个工作小提琴。 https://jsfiddle.net/du6dbdu6/

答案 1 :(得分:0)

如果您可以更改商店数组的结构,那么您可以更改它并根据标题从头开始分组。

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

 [
   {
    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的createMarkers,它是一个计算属性,不会返回任何内容。如果加载完成,您只想将属性marker添加到商店。因此,您可以使用.subscribe而不是使用计算,并执行以下操作:

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());
    } 
  });

希望这有帮助。