Ich versuche, eine Reihe von Objekten zu ordnen, in diesem Zusammenhang Häuser, und ich versuche, eine Funktion zu schreiben, mit der Benutzer die Reihe von Häusern nach der Entfernung eines Orientierungspunkts ordnen können. Angenommen, ich habe die folgenden Daten von einer API zurückgegeben, die ich über AJAX aufrufe:

"data" : [
    {
        'id' : 123,
        'address' : '12 street name',
        'city' : 'City Name',
        'landmarks' : [
            {
                'name' : 'landmark one',
                'distanceInMiles' : 0.6
            },
            {
                'name' : 'landmark two',
                'distanceInMiles' : 0.4
            }
        ]
    },
    {
        'id' : 345,
        'address' : '22 street name',
        'city' : 'City Name',
        'landmarks' : [
            {
                'name' : 'landmark one',
                'distanceInMiles' : 0.2
            },
            {
                'name' : 'landmark three',
                'distanceInMiles' : 0.1
            }
        ]
    },
    {
        'id' : 456,
        'address' : '28 street name',
        'city' : 'City Name',
        'landmarks' : [
            {
                'name' : 'landmark six',
                'distanceInMiles' : 8.2
            },
            {
                'name' : 'landmark seven',
                'distanceInMiles' : 1.6
            }
        ]
    }
]

Ich habe bereits einen Code, der die Häuser zurückgibt, die ein bestimmtes Wahrzeichen enthalten, z. Filtern Sie dieses Array, um Häuser mit dem Orientierungspunkt "Orientierungspunkt Eins" zurückzugeben, und ich speichere diese gefilterten Daten in einem separaten Array. Aber ich möchte jetzt noch einen Schritt weiter gehen und mein gefiltertes Ergebnisarray basierend auf dem Wert distanceInMiles anhand des ausgewählten Orientierungspunkts sortieren.

Wenn ich mich an diesen Kontext halte, versuche ich, einen Code zu schreiben, der zuerst die beiden Häuser mit der Adresse "22 Straßenname" und dann das Haus mit der Adresse "12 Straßenname" zurückgibt, da das Haus "22 Straßenname" näher ist das eine als das andere markieren.

Ich verwende _loadash als Dienstprogrammbibliothek, habe jedoch Schwierigkeiten zu verstehen, wie das gefilterte Array nach der Entfernung "Landmark One" sortiert wird. Irgendwelche Ideen?

Jede Hilfe wäre sehr dankbar.

5
Jamie Bradley 13 Aug. 2015 im 19:20

6 Antworten

Beste Antwort
var data = [
 {
  "id" : 123,
  "address" : "12 street name",
  "city" : "City Name",
  "landmarks" : [
   {
    "name" : "landmark one",
    "distanceInMiles" : 0.6
   },
   {
    "name" : "landmark two",
    "distanceInMiles" : 0.4
   }
  ]
 },
 {
  "id" : 345,
  "address" : "22 street name",
  "city" : "City Name",
  "landmarks" : [
   {
    "name" : "landmark one",
    "distanceInMiles" : 0.2
   },
   {
    "name" : "landmark three",
    "distanceInMiles" : 0.1
   }
  ]
 },
 {
  "id" : 456,
  "address" : "28 street name",
  "city" : "City Name",
  "landmarks" : [
   {
    "name" : "landmark six",
    "distanceInMiles" : 8.2
   },
   {
    "name" : "landmark seven",
    "distanceInMiles" : 1.6
   }
  ]
 }
];

function sortByLandmarkDistance(name) {
    var getDistance = function(house) {
        var minDistance = Infinity;

        for(var i = 0; i < house.landmarks.length; ++i)
            if(house.landmarks[i].name === name)
            	minDistance = Math.min(minDistance, house.landmarks[i].distanceInMiles);

        return minDistance;
    };

    return data.sort(function(a, b) {
		return getDistance(a) - getDistance(b);
    });
}
    
// Sort houses by distance from 'landmark one'
var sorted = sortByLandmarkDistance('landmark one');
document.body.innerHTML = '<pre>' + JSON.stringify(sorted, null, '    ') + '</pre>';
0
Joshua Coussard 13 Aug. 2015 im 16:38

Verwenden Sie die array.sort -Methode mit a benutzerdefinierte Sortierfunktion. Sort sucht nach -1, 0 oder 1. Alles was Sie tun müssen, ist die Entfernung b von a und der Bratsche zu subtrahieren!

function sortLandmarkDistanc1 (a, b) {
    return a.landmarks[0].distanceInMiles - b.landmarks[0].distanceInMiles;
}
data.sort(sortLandmarkDistanc1);
var data = [
		{
			'id' : 123,
			'address' : '12 street name',
			'city' : 'City Name',
			'landmarks' : [
				{
					'name' : 'landmark one',
					'distanceInMiles' : 0.6
				},
				{
					'name' : 'landmark two',
					'distanceInMiles' : 0.4
				}
			]
		},
		{
			'id' : 345,
			'address' : '22 street name',
			'city' : 'City Name',
			'landmarks' : [
				{
					'name' : 'landmark one',
					'distanceInMiles' : 0.2
				},
				{
					'name' : 'landmark three',
					'distanceInMiles' : 0.1
				}
			]
		},
		{
			'id' : 456,
			'address' : '28 street name',
			'city' : 'City Name',
			'landmarks' : [
				{
					'name' : 'landmark six',
					'distanceInMiles' : 8.2
				},
				{
					'name' : 'landmark seven',
					'distanceInMiles' : 1.6
				}
			]
		}
	];

function sortLandmarkDistanc1 (a, b) {
	return a.landmarks[0].distanceInMiles - b.landmarks[0].distanceInMiles;
}
/* ignore this, just for showing results */
function repeatString(a,c){out="";for(var d=0;d<c;d++)out+=a;return out}
function dump(a,c){c="number"!==typeof c?0:c;var d=typeof a,b=d;switch(d){case "number":case "boolean":b+=": "+a;break;case "string":b+="("+a.length+'): "'+a+'"';break;case "object":if(null===a)b="null";else if("[object Array]"===Object.prototype.toString.call(a)){b="array("+a.length+"): {\n";for(d=0;d<a.length;d++)b+=repeatString("   ",c)+"   ["+d+"]:  "+dump(a[d],"none",c+1)+"\n";b+=repeatString("   ",c)+"}"}else{sContents="{\n";cnt=0;for(var e in a)sContents+=repeatString("   ",c)+"   "+e+":  "+
dump(a[e],"none",c+1)+"\n",cnt++;sContents+=repeatString("   ",c)+"}";b+="("+cnt+"): "+sContents}}return b};
/*-----------------------*/
document.getElementById('before').innerHTML = dump(data);
document.getElementById('after').innerHTML = dump(data.sort(sortLandmarkDistanc1));
<table>
  <tbody>
    <tr>
      <td>
<h1>Before</h1>
<pre id="before"></pre>
        </td>
      <td>
<h1>After</h1>
<pre id="after"></pre>
        </td>
      </tr>
    </tbody>
  </table>
0
wizzwizz4 13 Aug. 2015 im 17:34

Erstellen Sie ein Array der Werte gepaart mit einem Array, das sie zählt (d. H. [0, 1, 2, ...]). Der von mir angegebene Code setzt voraus, dass Ihr (gefiltertes) Array dieses Format hat:

filtered = [
{
    id: 123,
    address: "12 Street Name",
    city: "City Name",
    landmark: {
        name: "landmark One"
        //and other landmark properties
    }
}, {
    id: 456,
    //and so on...

Code:

var content = [];
var order = [];
var x;
for (x = 0; x < filtered.length; x++) {
    content[x] = filtered[x].landmark.distanceInMiles;
    order[x] = x;
}
var sorted = false;
var y;
while (!sorted) {
    sorted = true;
    for (x = 1; x < content.length; x++) {
        if (content[x-1] > content[x]) {
            sorted = false;
            y = content[x];
            content[x] = content[x-1];
            content[x-1] = y;
            y = order[x];
            order[x] = order[x-1];
            order[x-1] = y;
        }
    }
}

Jetzt sollte das Array order die richtige Reihenfolge der Häuser enthalten, kleinste bis größte.

0
wizzwizz4 13 Aug. 2015 im 18:20

Filtern und Sortieren:

// first you call the filter function that will return a new filtered array
var myFilteredAndSorteredArray = arr.filter(function(item) {
  // here, you must return true if the item has the "landmark one"
  // the map function returns a new array converting for what you're returning
  // so, you return their names and use the indexOf to see if it has "landmark one"
  return item.landmarks.map(function(land) { return land.name; }).indexOf("landmark one") > -1;
}).sort(function(a, b) {
  // now you sort the filtered array
  // so, you use the same map function to get exactly the "landmark one"
  var landA = a.landmarks[a.landmarks.map(function(land) { return land.name; }).indexOf("landmark one")];
  var landB = b.landmarks[b.landmarks.map(function(land) { return land.name; }).indexOf("landmark one")];
  // you always compare the second parameter with the first one
  // since you want to return the smaller distance, you use the < operator
  return landB.distanceInMiles < landA.distanceInMiles;
}));
0
Buzinas 13 Aug. 2015 im 17:02

Hier finden Sie ein ziemlich genaues Beispiel dafür:

http://www.w3schools.com/jsref/jsref_sort.asp

In Ihrem Fall würde die Funktion also ungefähr so aussehen:

var data = getArrayFromAJAXHere();

data.sort(function(a,b){return a.landmarks[0].distanceInMiles - b.landmarks[0].distanceInMiles; })

Dadurch wird das Array nach Entfernung zum Standort in aufsteigender Reihenfolge sortiert.

0
stubsthewizard 13 Aug. 2015 im 16:41

Mit lodash können Sie filter () und sortBy () als Kette:

_(data)
    .filter(function(item) {
        return _.any(item.landmarks, {
            name: 'landmark one'
        });
    })
    .sortBy(function(item) {
        return _.find(item.landmarks, {
            name: 'landmark one'
        }).distanceInMiles;
    })
    .value();
0
Adam Boduch 13 Aug. 2015 im 21:27