Getting An Arbitrary Type From Reduce
I'm doing a very simple operation. I'm sorting through a bunch of locations in a map to create an enclosing circle, like so:
var maxLong: Double = -180
var maxLat: Double = -180
var minLong: Double = 180
var minLat: Double = 180
for coord in inCoordinates {
maxLong = max(coord.longitude, maxLong)
maxLat = max(coord.latitude, maxLat)
minLong = min(coord.longitude, minLong)
minLat = min(coord.latitude, minLat)
}
let nw: CLLocation = CLLocation(latitude: maxLat, longitude: minLong)
let se: CLLocation = CLLocation(latitude: minLat, longitude: maxLong)
let center = CLLocationCoordinate2D(latitude: (maxLat + minLat) / 2.0, longitude: (maxLong + minLong) / 2.0)
let radiusInMeters = abs(nw.distance(from: se)) / 2.0
return MKCircle(center: center, radius: radiusInMeters)
Pretty straightforward (Yeah, I know about the IDL issue, but I want to keep this simple).
What I'd like to know, is if there were some way I could boil the loop into a variant of reduce, where you would end up with something like this:
let enclosingRect: MKMapRect = inCoordinates.magikalReduce {
// Magic Happens Here -Queue Doug Henning GIF
}
So the returned rect contains the distilled points.
Yeah, I know that I can simply extend Array (with maybe a type qualifier) to do this with a calculated property, but that sort of defeats the purpose of this. The above is fairly efficient, and I'd rather not add overhead, just to be fancy (Which means, even if I could do it, it might be too inefficient to use).
This is more of a curiosity exploration than a technical need. The above code does fine for me, and is relatively zippy.
swift algorithm mapkit reduce
add a comment |
I'm doing a very simple operation. I'm sorting through a bunch of locations in a map to create an enclosing circle, like so:
var maxLong: Double = -180
var maxLat: Double = -180
var minLong: Double = 180
var minLat: Double = 180
for coord in inCoordinates {
maxLong = max(coord.longitude, maxLong)
maxLat = max(coord.latitude, maxLat)
minLong = min(coord.longitude, minLong)
minLat = min(coord.latitude, minLat)
}
let nw: CLLocation = CLLocation(latitude: maxLat, longitude: minLong)
let se: CLLocation = CLLocation(latitude: minLat, longitude: maxLong)
let center = CLLocationCoordinate2D(latitude: (maxLat + minLat) / 2.0, longitude: (maxLong + minLong) / 2.0)
let radiusInMeters = abs(nw.distance(from: se)) / 2.0
return MKCircle(center: center, radius: radiusInMeters)
Pretty straightforward (Yeah, I know about the IDL issue, but I want to keep this simple).
What I'd like to know, is if there were some way I could boil the loop into a variant of reduce, where you would end up with something like this:
let enclosingRect: MKMapRect = inCoordinates.magikalReduce {
// Magic Happens Here -Queue Doug Henning GIF
}
So the returned rect contains the distilled points.
Yeah, I know that I can simply extend Array (with maybe a type qualifier) to do this with a calculated property, but that sort of defeats the purpose of this. The above is fairly efficient, and I'd rather not add overhead, just to be fancy (Which means, even if I could do it, it might be too inefficient to use).
This is more of a curiosity exploration than a technical need. The above code does fine for me, and is relatively zippy.
swift algorithm mapkit reduce
add a comment |
I'm doing a very simple operation. I'm sorting through a bunch of locations in a map to create an enclosing circle, like so:
var maxLong: Double = -180
var maxLat: Double = -180
var minLong: Double = 180
var minLat: Double = 180
for coord in inCoordinates {
maxLong = max(coord.longitude, maxLong)
maxLat = max(coord.latitude, maxLat)
minLong = min(coord.longitude, minLong)
minLat = min(coord.latitude, minLat)
}
let nw: CLLocation = CLLocation(latitude: maxLat, longitude: minLong)
let se: CLLocation = CLLocation(latitude: minLat, longitude: maxLong)
let center = CLLocationCoordinate2D(latitude: (maxLat + minLat) / 2.0, longitude: (maxLong + minLong) / 2.0)
let radiusInMeters = abs(nw.distance(from: se)) / 2.0
return MKCircle(center: center, radius: radiusInMeters)
Pretty straightforward (Yeah, I know about the IDL issue, but I want to keep this simple).
What I'd like to know, is if there were some way I could boil the loop into a variant of reduce, where you would end up with something like this:
let enclosingRect: MKMapRect = inCoordinates.magikalReduce {
// Magic Happens Here -Queue Doug Henning GIF
}
So the returned rect contains the distilled points.
Yeah, I know that I can simply extend Array (with maybe a type qualifier) to do this with a calculated property, but that sort of defeats the purpose of this. The above is fairly efficient, and I'd rather not add overhead, just to be fancy (Which means, even if I could do it, it might be too inefficient to use).
This is more of a curiosity exploration than a technical need. The above code does fine for me, and is relatively zippy.
swift algorithm mapkit reduce
I'm doing a very simple operation. I'm sorting through a bunch of locations in a map to create an enclosing circle, like so:
var maxLong: Double = -180
var maxLat: Double = -180
var minLong: Double = 180
var minLat: Double = 180
for coord in inCoordinates {
maxLong = max(coord.longitude, maxLong)
maxLat = max(coord.latitude, maxLat)
minLong = min(coord.longitude, minLong)
minLat = min(coord.latitude, minLat)
}
let nw: CLLocation = CLLocation(latitude: maxLat, longitude: minLong)
let se: CLLocation = CLLocation(latitude: minLat, longitude: maxLong)
let center = CLLocationCoordinate2D(latitude: (maxLat + minLat) / 2.0, longitude: (maxLong + minLong) / 2.0)
let radiusInMeters = abs(nw.distance(from: se)) / 2.0
return MKCircle(center: center, radius: radiusInMeters)
Pretty straightforward (Yeah, I know about the IDL issue, but I want to keep this simple).
What I'd like to know, is if there were some way I could boil the loop into a variant of reduce, where you would end up with something like this:
let enclosingRect: MKMapRect = inCoordinates.magikalReduce {
// Magic Happens Here -Queue Doug Henning GIF
}
So the returned rect contains the distilled points.
Yeah, I know that I can simply extend Array (with maybe a type qualifier) to do this with a calculated property, but that sort of defeats the purpose of this. The above is fairly efficient, and I'd rather not add overhead, just to be fancy (Which means, even if I could do it, it might be too inefficient to use).
This is more of a curiosity exploration than a technical need. The above code does fine for me, and is relatively zippy.
swift algorithm mapkit reduce
swift algorithm mapkit reduce
asked Nov 20 at 18:57
Little Green Viper
2,04842743
2,04842743
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
Do you mean
// calculate the enclosing rect with `reduce` and `union`, you have to create an `MKMapRect` from each coordinate
let enclosingRect = inCoordinates.reduce(MKMapRect.null) { $0.union(MKMapRect(origin: MKMapPoint($1), size: MKMapSize())) }
This is really what I was looking for. Good show!
– Little Green Viper
Nov 20 at 19:33
OrinCoordinates.reduce(MKMapRect.null) { $0.union(MKMapRect(origin: MKMapPoint($1), size: MKMapSize())) }without an intermediate array.
– Martin R
Nov 20 at 19:51
@MartinR That's indeed better, thanks.
– vadian
Nov 20 at 19:53
add a comment |
You can create a struct for holding the min/max longitude and latitude values, then use reduce, where you use the initial values for these for creating an initial result, then creating an updated version of the struct with the necessary min/max calculations.
struct MinMaxCoordinates {
let maxLong:Double
let maxLat:Double
let minLong:Double
let minLat:Double
}
let minMaxCoordinates = inCoordinates.reduce(MinMaxCoordinates(maxLong: -180, maxLat: -180, minLong: 180, minLat: 180), {minMax, coord in
return MinMaxCoordinates(maxLong: max(minMax.maxLong, coord.longitude), maxLat: max(minMax.maxLat, coord.latitude), minLong: min(minMax.minLong, coord.longitude), minLat: max(minMax.minLat, coord.latitude))
})
let nw: CLLocation = CLLocation(latitude: minMaxCoordinates.maxLat, longitude: minMaxCoordinates.minLong)
let se: CLLocation = CLLocation(latitude: minMaxCoordinates.minLat, longitude: minMaxCoordinates.maxLong)
let center = CLLocationCoordinate2D(latitude: (minMaxCoordinates.maxLat + minMaxCoordinates.minLat) / 2.0, longitude: (minMaxCoordinates.maxLong + minMaxCoordinates.minLong) / 2.0)
let radiusInMeters = abs(nw.distance(from: se)) / 2.0
return MKCircle(center: center, radius: radiusInMeters)
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53399754%2fgetting-an-arbitrary-type-from-reduce%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Do you mean
// calculate the enclosing rect with `reduce` and `union`, you have to create an `MKMapRect` from each coordinate
let enclosingRect = inCoordinates.reduce(MKMapRect.null) { $0.union(MKMapRect(origin: MKMapPoint($1), size: MKMapSize())) }
This is really what I was looking for. Good show!
– Little Green Viper
Nov 20 at 19:33
OrinCoordinates.reduce(MKMapRect.null) { $0.union(MKMapRect(origin: MKMapPoint($1), size: MKMapSize())) }without an intermediate array.
– Martin R
Nov 20 at 19:51
@MartinR That's indeed better, thanks.
– vadian
Nov 20 at 19:53
add a comment |
Do you mean
// calculate the enclosing rect with `reduce` and `union`, you have to create an `MKMapRect` from each coordinate
let enclosingRect = inCoordinates.reduce(MKMapRect.null) { $0.union(MKMapRect(origin: MKMapPoint($1), size: MKMapSize())) }
This is really what I was looking for. Good show!
– Little Green Viper
Nov 20 at 19:33
OrinCoordinates.reduce(MKMapRect.null) { $0.union(MKMapRect(origin: MKMapPoint($1), size: MKMapSize())) }without an intermediate array.
– Martin R
Nov 20 at 19:51
@MartinR That's indeed better, thanks.
– vadian
Nov 20 at 19:53
add a comment |
Do you mean
// calculate the enclosing rect with `reduce` and `union`, you have to create an `MKMapRect` from each coordinate
let enclosingRect = inCoordinates.reduce(MKMapRect.null) { $0.union(MKMapRect(origin: MKMapPoint($1), size: MKMapSize())) }
Do you mean
// calculate the enclosing rect with `reduce` and `union`, you have to create an `MKMapRect` from each coordinate
let enclosingRect = inCoordinates.reduce(MKMapRect.null) { $0.union(MKMapRect(origin: MKMapPoint($1), size: MKMapSize())) }
edited Nov 20 at 19:53
answered Nov 20 at 19:29
vadian
141k13150168
141k13150168
This is really what I was looking for. Good show!
– Little Green Viper
Nov 20 at 19:33
OrinCoordinates.reduce(MKMapRect.null) { $0.union(MKMapRect(origin: MKMapPoint($1), size: MKMapSize())) }without an intermediate array.
– Martin R
Nov 20 at 19:51
@MartinR That's indeed better, thanks.
– vadian
Nov 20 at 19:53
add a comment |
This is really what I was looking for. Good show!
– Little Green Viper
Nov 20 at 19:33
OrinCoordinates.reduce(MKMapRect.null) { $0.union(MKMapRect(origin: MKMapPoint($1), size: MKMapSize())) }without an intermediate array.
– Martin R
Nov 20 at 19:51
@MartinR That's indeed better, thanks.
– vadian
Nov 20 at 19:53
This is really what I was looking for. Good show!
– Little Green Viper
Nov 20 at 19:33
This is really what I was looking for. Good show!
– Little Green Viper
Nov 20 at 19:33
Or
inCoordinates.reduce(MKMapRect.null) { $0.union(MKMapRect(origin: MKMapPoint($1), size: MKMapSize())) } without an intermediate array.– Martin R
Nov 20 at 19:51
Or
inCoordinates.reduce(MKMapRect.null) { $0.union(MKMapRect(origin: MKMapPoint($1), size: MKMapSize())) } without an intermediate array.– Martin R
Nov 20 at 19:51
@MartinR That's indeed better, thanks.
– vadian
Nov 20 at 19:53
@MartinR That's indeed better, thanks.
– vadian
Nov 20 at 19:53
add a comment |
You can create a struct for holding the min/max longitude and latitude values, then use reduce, where you use the initial values for these for creating an initial result, then creating an updated version of the struct with the necessary min/max calculations.
struct MinMaxCoordinates {
let maxLong:Double
let maxLat:Double
let minLong:Double
let minLat:Double
}
let minMaxCoordinates = inCoordinates.reduce(MinMaxCoordinates(maxLong: -180, maxLat: -180, minLong: 180, minLat: 180), {minMax, coord in
return MinMaxCoordinates(maxLong: max(minMax.maxLong, coord.longitude), maxLat: max(minMax.maxLat, coord.latitude), minLong: min(minMax.minLong, coord.longitude), minLat: max(minMax.minLat, coord.latitude))
})
let nw: CLLocation = CLLocation(latitude: minMaxCoordinates.maxLat, longitude: minMaxCoordinates.minLong)
let se: CLLocation = CLLocation(latitude: minMaxCoordinates.minLat, longitude: minMaxCoordinates.maxLong)
let center = CLLocationCoordinate2D(latitude: (minMaxCoordinates.maxLat + minMaxCoordinates.minLat) / 2.0, longitude: (minMaxCoordinates.maxLong + minMaxCoordinates.minLong) / 2.0)
let radiusInMeters = abs(nw.distance(from: se)) / 2.0
return MKCircle(center: center, radius: radiusInMeters)
add a comment |
You can create a struct for holding the min/max longitude and latitude values, then use reduce, where you use the initial values for these for creating an initial result, then creating an updated version of the struct with the necessary min/max calculations.
struct MinMaxCoordinates {
let maxLong:Double
let maxLat:Double
let minLong:Double
let minLat:Double
}
let minMaxCoordinates = inCoordinates.reduce(MinMaxCoordinates(maxLong: -180, maxLat: -180, minLong: 180, minLat: 180), {minMax, coord in
return MinMaxCoordinates(maxLong: max(minMax.maxLong, coord.longitude), maxLat: max(minMax.maxLat, coord.latitude), minLong: min(minMax.minLong, coord.longitude), minLat: max(minMax.minLat, coord.latitude))
})
let nw: CLLocation = CLLocation(latitude: minMaxCoordinates.maxLat, longitude: minMaxCoordinates.minLong)
let se: CLLocation = CLLocation(latitude: minMaxCoordinates.minLat, longitude: minMaxCoordinates.maxLong)
let center = CLLocationCoordinate2D(latitude: (minMaxCoordinates.maxLat + minMaxCoordinates.minLat) / 2.0, longitude: (minMaxCoordinates.maxLong + minMaxCoordinates.minLong) / 2.0)
let radiusInMeters = abs(nw.distance(from: se)) / 2.0
return MKCircle(center: center, radius: radiusInMeters)
add a comment |
You can create a struct for holding the min/max longitude and latitude values, then use reduce, where you use the initial values for these for creating an initial result, then creating an updated version of the struct with the necessary min/max calculations.
struct MinMaxCoordinates {
let maxLong:Double
let maxLat:Double
let minLong:Double
let minLat:Double
}
let minMaxCoordinates = inCoordinates.reduce(MinMaxCoordinates(maxLong: -180, maxLat: -180, minLong: 180, minLat: 180), {minMax, coord in
return MinMaxCoordinates(maxLong: max(minMax.maxLong, coord.longitude), maxLat: max(minMax.maxLat, coord.latitude), minLong: min(minMax.minLong, coord.longitude), minLat: max(minMax.minLat, coord.latitude))
})
let nw: CLLocation = CLLocation(latitude: minMaxCoordinates.maxLat, longitude: minMaxCoordinates.minLong)
let se: CLLocation = CLLocation(latitude: minMaxCoordinates.minLat, longitude: minMaxCoordinates.maxLong)
let center = CLLocationCoordinate2D(latitude: (minMaxCoordinates.maxLat + minMaxCoordinates.minLat) / 2.0, longitude: (minMaxCoordinates.maxLong + minMaxCoordinates.minLong) / 2.0)
let radiusInMeters = abs(nw.distance(from: se)) / 2.0
return MKCircle(center: center, radius: radiusInMeters)
You can create a struct for holding the min/max longitude and latitude values, then use reduce, where you use the initial values for these for creating an initial result, then creating an updated version of the struct with the necessary min/max calculations.
struct MinMaxCoordinates {
let maxLong:Double
let maxLat:Double
let minLong:Double
let minLat:Double
}
let minMaxCoordinates = inCoordinates.reduce(MinMaxCoordinates(maxLong: -180, maxLat: -180, minLong: 180, minLat: 180), {minMax, coord in
return MinMaxCoordinates(maxLong: max(minMax.maxLong, coord.longitude), maxLat: max(minMax.maxLat, coord.latitude), minLong: min(minMax.minLong, coord.longitude), minLat: max(minMax.minLat, coord.latitude))
})
let nw: CLLocation = CLLocation(latitude: minMaxCoordinates.maxLat, longitude: minMaxCoordinates.minLong)
let se: CLLocation = CLLocation(latitude: minMaxCoordinates.minLat, longitude: minMaxCoordinates.maxLong)
let center = CLLocationCoordinate2D(latitude: (minMaxCoordinates.maxLat + minMaxCoordinates.minLat) / 2.0, longitude: (minMaxCoordinates.maxLong + minMaxCoordinates.minLong) / 2.0)
let radiusInMeters = abs(nw.distance(from: se)) / 2.0
return MKCircle(center: center, radius: radiusInMeters)
answered Nov 20 at 19:31
Dávid Pásztor
20.2k72547
20.2k72547
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53399754%2fgetting-an-arbitrary-type-from-reduce%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown