可以在 objective c 中使用 swift 中的数组缩减概念吗?
It is possible to use array reduce concept from swift in objective c?
我在 Swift 中有这行代码:
let graphPoints:[Int] = [4, 2, 6, 4, 5, 8, 3]
let average = graphPoints.reduce(0, combine: +) / graphPoints.count
可以在objective c代码中"translate"这行代码吗?
我不太清楚 reduce combine 概念是如何工作的。我读到了它,但仍然不清楚。
我从本教程中获取了代码:http://www.raywenderlich.com/90693/modern-core-graphics-with-swift-part-2
请帮忙。谢谢
假设您有一些 NSNumber
存储在 NSArray
中,您可以使用此 KVC 集合运算符:
NSArray *someNumbers = @[@0, @1.1, @2, @3.4, @5, @6.7];
NSNumber *average = [someNumbers valueForKeyPath:@"@avg.self"];
reduce
函数在 Objective-C 中不是标准的。不过,您可以将其实现为 NSArray
的扩展。
在您的例子中,您在 Swift 中有一个 Int
的数组。你不能在 Objective-C 中拥有它,你需要一个 NSNumber
.
的数组
这里是 reduce
的一个实现,应该适用于您的情况:
@implementation NSArray (Helpers)
- (NSInteger)reduceInt:(NSInteger)initial combine:(NSInteger (^)(NSInteger acum, NSInteger element))block {
if (!self) {
return initial;
}
NSInteger acum = initial;
for (id element in self) {
if ([element isKindOfClass:[NSNumber class]]) {
acum = block(acum, [(NSNumber *)element integerValue]);
}
}
return acum;
}
@end
然后您可以将它与您的数组一起使用,如下所示:
NSArray *a = @[@1, @2, @3];
NSInteger result = [a reduceInt:0 combine:^NSInteger(NSInteger acum, NSInteger element) {
return acum + element;
}];
how to translate reduce to ObjC (or better to say how to solve your "average problem" in Objective C) 完美地回答了 André Slotta。 swift reduce 远不止于此。我将尝试回答你问题的第二部分,这个概念在 swift
中是如何工作的
func reduce<T>(initial: T, @noescape combine: (T, Self.Generator.Element) throws -> T) rethrows -> T
Return the result
of repeatedly calling combine with an accumulated value initialized to
initial and each element of self, in turn, i.e. return
combine(combine(...combine(combine(initial, self[0]),
self[1]),...self[count-2]), self[count-1]).
let arr: Array<Int> = [1,2,3,4,5]
let sum = arr.reduce(0) { (sum, i) -> Int in
return sum + i
}
print(sum) // 15
// this is an quasi equivalent of
var sum1 = 0 // ..... reduce(0)....
arr.forEach { (elementValue) -> Void in
sum1 = sum1 + elementValue // ...{ return sum + i }
}
print(sum1) // 15 reduce function will return accumulated inital value
// reduce is part of SequenceType protocol, that is why
let arr1 = ["H","e","l","l","o"," ","w","o","r","l","d"]
let str = arr1.reduce("") { (str, s) -> String in
str + s
}
// works the same way
print(str) // "Hello world"
// let have a litle bit more complex example, to see how powerful, useful and easy to use reduce can be
let dict = arr1.reduce([:]) { (var dict, s) -> Dictionary<Int,String> in
let i = dict.count
dict.updateValue(s, forKey: i+1)
return dict
}
print(dict) // [11: "d", 10: "l", 2: "e", 4: "l", 9: "r", 5: "o", 6: " ", 7: "w", 3: "l", 1: "H", 8: "o"]
写一个 NSArray 扩展
- (NSInteger)reduceStart:(NSInteger)start combine:(NSInteger(^)(NSInteger x, NSInteger y))combine {
for (NSNumber* n in self) {
if ([n isKindOfClass:[NSNumber class]]) {
start = combine (start, n.integerValue);
}
}
return start;
}
修正我犯的所有错误,就是这样。只是不如 Swift 灵活。
对于 Objective-C,我会将高阶函数添加到此答案列表中:https://github.com/fanpyi/Higher-Order-Functions
#import <Foundation/Foundation.h>
typedef id (^ReduceBlock)(id accumulator,id item);
@interface NSArray (HigherOrderFunctions)
-(id)reduce:(id)initial combine:(ReduceBlock)combine;
@end
#import "NSArray+HigherOrderFunctions.h"
@implementation NSArray (HigherOrderFunctions)
-(id)reduce:(id)initial combine:(ReduceBlock)combine{
id accumulator = initial;
for (id item in self) {
accumulator = combine(accumulator, item);
}
return accumulator;
}
@end
示例:
NSArray *numbers = @[@5,@7,@3,@8];
NSNumber *sum = [numbers reduce:@0 combine:^id(id accumulator, id item) {
return @([item intValue] + [accumulator intValue]);
}];
NSNumber *multiplier = [numbers reduce:@1 combine:^id(id accumulator, id item) {
return @([item intValue] * [accumulator intValue]);
}];
NSLog(@"sum=%@,multiplier=%@",sum,multiplier);
我在 Swift 中有这行代码:
let graphPoints:[Int] = [4, 2, 6, 4, 5, 8, 3]
let average = graphPoints.reduce(0, combine: +) / graphPoints.count
可以在objective c代码中"translate"这行代码吗?
我不太清楚 reduce combine 概念是如何工作的。我读到了它,但仍然不清楚。
我从本教程中获取了代码:http://www.raywenderlich.com/90693/modern-core-graphics-with-swift-part-2
请帮忙。谢谢
假设您有一些 NSNumber
存储在 NSArray
中,您可以使用此 KVC 集合运算符:
NSArray *someNumbers = @[@0, @1.1, @2, @3.4, @5, @6.7];
NSNumber *average = [someNumbers valueForKeyPath:@"@avg.self"];
reduce
函数在 Objective-C 中不是标准的。不过,您可以将其实现为 NSArray
的扩展。
在您的例子中,您在 Swift 中有一个 Int
的数组。你不能在 Objective-C 中拥有它,你需要一个 NSNumber
.
这里是 reduce
的一个实现,应该适用于您的情况:
@implementation NSArray (Helpers)
- (NSInteger)reduceInt:(NSInteger)initial combine:(NSInteger (^)(NSInteger acum, NSInteger element))block {
if (!self) {
return initial;
}
NSInteger acum = initial;
for (id element in self) {
if ([element isKindOfClass:[NSNumber class]]) {
acum = block(acum, [(NSNumber *)element integerValue]);
}
}
return acum;
}
@end
然后您可以将它与您的数组一起使用,如下所示:
NSArray *a = @[@1, @2, @3];
NSInteger result = [a reduceInt:0 combine:^NSInteger(NSInteger acum, NSInteger element) {
return acum + element;
}];
how to translate reduce to ObjC (or better to say how to solve your "average problem" in Objective C) 完美地回答了 André Slotta。 swift reduce 远不止于此。我将尝试回答你问题的第二部分,这个概念在 swift
中是如何工作的func reduce<T>(initial: T, @noescape combine: (T, Self.Generator.Element) throws -> T) rethrows -> T
Return the result of repeatedly calling combine with an accumulated value initialized to initial and each element of self, in turn, i.e. return combine(combine(...combine(combine(initial, self[0]), self[1]),...self[count-2]), self[count-1]).
let arr: Array<Int> = [1,2,3,4,5]
let sum = arr.reduce(0) { (sum, i) -> Int in
return sum + i
}
print(sum) // 15
// this is an quasi equivalent of
var sum1 = 0 // ..... reduce(0)....
arr.forEach { (elementValue) -> Void in
sum1 = sum1 + elementValue // ...{ return sum + i }
}
print(sum1) // 15 reduce function will return accumulated inital value
// reduce is part of SequenceType protocol, that is why
let arr1 = ["H","e","l","l","o"," ","w","o","r","l","d"]
let str = arr1.reduce("") { (str, s) -> String in
str + s
}
// works the same way
print(str) // "Hello world"
// let have a litle bit more complex example, to see how powerful, useful and easy to use reduce can be
let dict = arr1.reduce([:]) { (var dict, s) -> Dictionary<Int,String> in
let i = dict.count
dict.updateValue(s, forKey: i+1)
return dict
}
print(dict) // [11: "d", 10: "l", 2: "e", 4: "l", 9: "r", 5: "o", 6: " ", 7: "w", 3: "l", 1: "H", 8: "o"]
写一个 NSArray 扩展
- (NSInteger)reduceStart:(NSInteger)start combine:(NSInteger(^)(NSInteger x, NSInteger y))combine {
for (NSNumber* n in self) {
if ([n isKindOfClass:[NSNumber class]]) {
start = combine (start, n.integerValue);
}
}
return start;
}
修正我犯的所有错误,就是这样。只是不如 Swift 灵活。
对于 Objective-C,我会将高阶函数添加到此答案列表中:https://github.com/fanpyi/Higher-Order-Functions
#import <Foundation/Foundation.h>
typedef id (^ReduceBlock)(id accumulator,id item);
@interface NSArray (HigherOrderFunctions)
-(id)reduce:(id)initial combine:(ReduceBlock)combine;
@end
#import "NSArray+HigherOrderFunctions.h"
@implementation NSArray (HigherOrderFunctions)
-(id)reduce:(id)initial combine:(ReduceBlock)combine{
id accumulator = initial;
for (id item in self) {
accumulator = combine(accumulator, item);
}
return accumulator;
}
@end
示例:
NSArray *numbers = @[@5,@7,@3,@8];
NSNumber *sum = [numbers reduce:@0 combine:^id(id accumulator, id item) {
return @([item intValue] + [accumulator intValue]);
}];
NSNumber *multiplier = [numbers reduce:@1 combine:^id(id accumulator, id item) {
return @([item intValue] * [accumulator intValue]);
}];
NSLog(@"sum=%@,multiplier=%@",sum,multiplier);