Swift:通过比较类型过滤协议数组(Swift: filter protocol array by comparing types)

(第一篇文章)

通常我能在这里或其他地方找到答案,但这次没有运气=(

问题:在Swift中,如何通过作为函数参数提供的实现类型过滤协议类型的数组?

protocol Aprotocol {
   var number:Int { get set }
}

class Aclass: Aprotocol {
    var number = 1
}

class AnotherClass: Aprotocol {
    var number = 1
}

var array:[Aprotocol] = [ Aclass(), AnotherClass(), Aclass() ]

func foo (parameter:Aprotocol) -> Int {
    return array.filter({ /* p in p.self == parameter.self  */ }).count
}

var bar:Aprotocol = // Aclass() or AnotherClass()

var result:Int = foo(bar) // should return 2 or 1, depending on bar type 

也许这根本不是正确的方法?

谢谢!


(first post)

usually im able to find answers here or elsewhere but no luck this time =(

Question: in Swift, how do you filter an array that is of a protocol type by an implementing type supplied as a function parameter?

protocol Aprotocol {
   var number:Int { get set }
}

class Aclass: Aprotocol {
    var number = 1
}

class AnotherClass: Aprotocol {
    var number = 1
}

var array:[Aprotocol] = [ Aclass(), AnotherClass(), Aclass() ]

func foo (parameter:Aprotocol) -> Int {
    return array.filter({ /* p in p.self == parameter.self  */ }).count
}

var bar:Aprotocol = // Aclass() or AnotherClass()

var result:Int = foo(bar) // should return 2 or 1, depending on bar type 

maybe this is not the right approach at all?

thanks!


原文:https://stackoverflow.com/questions/30823554
2022-03-19 14:03

满意答案

我可以看到这个命令的一些问题:

db.location.aggregate([
 {$match : { FirstName: { $nin : [" "] } } },
 {$group: {_id : "$DeviceId" } },
 {$project: { "DeviceId" : 1 } }
])
  1. $match阶段与您问题中提供的文档不匹配,因为您提供的文档具有"FirstName" : " "因此该文档将匹配$in而不是$nin
  2. 如果$match阶段更改为$in那么它将发出一个文档,分组阶段将有一些工作,但分组阶段只配置为返回_id属性,因此它返回以下中间文档:

    {
        "_id" : "89984320001499681816"
    }
    
  3. $project阶段尝试投影"DeviceId"但分组阶段的结果包含_id属性,因此您无法从该文档投影DeviceId属性。

  4. 当您的聚合管道到达forEach函数时,文档中没有DeviceId,FirstName或LastName属性。

要进一步了解聚合管道内发生的情况,您可以运行此查询:

db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } },
 {$project: { "DeviceId" : 1, FirstName: 1, LastName: 1 } }
]).forEach(
  function(obj) {
      print(obj);
  }
);

或者,只需自己运行管道中的每个阶段并查看每个状态的输出,因为这将成为下一阶段的输入。 所以,例如:

这个命令......

db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } }
])

...返回:

{
    "_id" : ObjectId("59d13b64c26584cd8b7a15c8"),
    "CreationDateTime" : ISODate("2017-09-26T06:39:29.105Z"),
    "DeviceId" : "89984320001499681816",
    "UserId" : UUID("bca0db12-2246-49a5-8703-b03fee45e50f"),
    "FirstName" : " ",
    "LastName" : ""
}

这个命令......

db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } },
 {$group: {_id : "$DeviceId" } }
])

...返回:

{
    "_id" : "89984320001499681816"
}

这个命令......

db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } },
 {$group: {_id : "$DeviceId" } },
 {$project: { "DeviceId" : 1 } }
])

...返回:

{
    "_id" : "89984320001499681816"
}

这应该清楚地表明,一旦添加$group阶段,您将丢失DeviceId,FirstName和LastName属性,因此它们无法在forEach函数中打印。


I can see a few issues with this command:

db.location.aggregate([
 {$match : { FirstName: { $nin : [" "] } } },
 {$group: {_id : "$DeviceId" } },
 {$project: { "DeviceId" : 1 } }
])
  1. The $match stage will not match the document supplied in your question because the document you supplied has "FirstName" : " " so that document would be matched by $in but not by $nin
  2. If the $match stage was changed to $in then it would emit a document and the grouping stage would have something to work on but the grouping stage is only configured to return an _id attribute so it returns the following intermediate document:

    {
        "_id" : "89984320001499681816"
    }
    
  3. The $project stage attempts to project "DeviceId" but the result of the grouping stage contains only an _id attribute so you cannot project a DeviceId attribute from that document.

  4. By the time your aggregation pipeline reaches the forEach funciton there is no DeviceId, FirstName or LastName attribute in the documents.

To further understand what's happening inside the aggregation pipeline you could run this query:

db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } },
 {$project: { "DeviceId" : 1, FirstName: 1, LastName: 1 } }
]).forEach(
  function(obj) {
      print(obj);
  }
);

Or, just run each stage in the pipeline on its own and review the output of each state since that becomes the input to the next stage. So, for example:

This command ...

db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } }
])

... returns:

{
    "_id" : ObjectId("59d13b64c26584cd8b7a15c8"),
    "CreationDateTime" : ISODate("2017-09-26T06:39:29.105Z"),
    "DeviceId" : "89984320001499681816",
    "UserId" : UUID("bca0db12-2246-49a5-8703-b03fee45e50f"),
    "FirstName" : " ",
    "LastName" : ""
}

This command ...

db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } },
 {$group: {_id : "$DeviceId" } }
])

... returns:

{
    "_id" : "89984320001499681816"
}

This command ...

db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } },
 {$group: {_id : "$DeviceId" } },
 {$project: { "DeviceId" : 1 } }
])

... returns:

{
    "_id" : "89984320001499681816"
}

This should make clear that once you add in the $group stage you lose the DeviceId, FirstName and LastName attributes hence they are not available for you to print in the forEach function.

相关问答

更多

mongodb聚合(co-monk)未定义的函数(mongodb aggregation (co-monk) undefined function)

蒙克斯的文件是迟钝的。 一位互联网英雄写道.col访问本机mongodb驱动程序,我可以做屎。 然而,我必须再次将它包装在一个承诺中,尽管没有probs。 var sessionSeen = yield new Promise(function (resolve, reject) { users.col.aggregate([ { $ma...

如何在MongoDB中累积结果(使用forEach?)?(How to accumulate results (with forEach?) in MongoDB?)

在光标上调用toArray而不是forEach : var a = db.my_collection.find( {timestamp : {$gt: 1343032491799}}, {_id:0,sid:1}).limit(20) .toArray().map(function(o){return o.sid;}) UPDATE 似乎您可以跳过toArray并直接转到map因为光标直接提供了该方法: var a = db.my_collection.find( {ti...

仅查询在MongoDB中具有值的文档(Query only documents that have values in it in MongoDB)

你可以使用$exists像这样: db.tweets.find( {"coordinates": {$exists: true}}, {"_id":0, "coordinates.coordinates": 1} ); you can use $exists like this: db.tweets.find( {"coordinates": {$exists: true}}, {"_id":0, "coordinates.coordinates": 1} );

如何从MongoDB聚合中读取未定义对象的属性?(How to read property of undefined object from MongoDB aggregation?)

你的函数getTotalTeamScore正在执行mongodb聚合函数,它是异步操作。 因此它不会立即返回结果,但在聚合返回DB记录之前,您的函数将被撤消。 所以你需要使用回调。 首先修改你的getTotalTeamScore函数,如下所示: module.exports.getTotalTeamScore = function (callback) { User.aggregate([ { $group: { _id: "$team", ...

MongoDB查询中forEach函数中的未定义值(Undefined value in forEach function in MongoDB query)

我可以看到这个命令的一些问题: db.location.aggregate([ {$match : { FirstName: { $nin : [" "] } } }, {$group: {_id : "$DeviceId" } }, {$project: { "DeviceId" : 1 } } ]) $match阶段与您问题中提供的文档不匹配,因为您提供的文档具有"FirstName" : " "因此该文档将匹配$in而不是$nin 如果$match阶段更改为$in那么它将发出一个文档...

MongoDB:forEach vs fetch + each(MongoDB: forEach vs fetch + each)

这两个语句在核心API级别基本相同,即获取光标并转换结果。 然而,性能有一个“核心”差异: .forEach()将“一次一个”转换游标结果并处理它提供的迭代器函数。 .fetch()从光标“一次性”获取“数组”,这意味着它在一次命中中都是“内存中”。 所以无论如何,在从查询的光标获取“核心”操作时,实际上“更快”。 但是,不评估每个游标迭代的“表达式”可能会“稍微快一点”,因此.fetch()可能在这里赢得“小”。 当然,最大的问题是“现在一切都在记忆中”,因此需要考虑“开销”。 同样,在.fet...

如何在forEach函数中检查mongodb文件中是否存在属性?(How to check if attribute exists in mongodb document in forEach function?)

Mongo shell是一个JavaScript shell,因此支持大多数标准JavaScript方法。 您可以像在JavaScript中的任何常规对象上一样检查属性是否存在 - 使用hasOwnProperty()方法: db.testData.find({}).forEach(function(x){ if (x.hasOwnProperty('name')) { // Do something } }) Mongo shell is a JavaScrip...

查询中的Mongodb $(Mongodb $within query)

引号不是问题,这只是有效的JSON。 问题是,minimongo还没有实现$。 Matt Debergalis 评论Minimongo的不完整状态 (2012年10月23日): 流行谈话最近的流量提醒我,minimongo带有一个健康的改进和扩展愿望清单。 [...] $ near,$ within和$ maxDistance。 您可能有更好的运气在您具有“真正的”mongodb访问权限的服务器中执行此操作,但如果客户端存储不具有相同的功能,我不确定它是如何工作的。 Minimongo的源代码可用...

我可以在MongoDB中的聚合查询中申请forEach吗?(Can I apply forEach in aggregate query in MongoDB?)

您无法使用聚合管道执行此操作。 您应该了解MongoDB聚合是应用于集合的一系列特殊运算符。 当您执行聚合管道时,MongoDB将运算符彼此管道连接,即运算符的输出成为以下运算符的输入。 每个运算符的结果是一个新的文档集合。 因此,您在上面尝试实现的内容可以简单地重写为以下管道,而无需首先创建文档数组: var collection = db.collection('member'), pipeline = [ { "$match": { createdDate: cur...

Mongodb查询中的未定义值(Undefined value in Mongodb query)

mongoDbHandleLoad()包含异步代码(对MongoDB的调用),因此它会在代码到达行return JSON.stringify(docs[docs.length-1]);之前返回undefined return JSON.stringify(docs[docs.length-1]); 。 你应该使用回调或Promises来取回你的结果。 我想首先你应该研究一下Javascript中的异步代码,特别是Node.js的约定。 mongoDbHandleLoad() contains as...

相关文章

更多

lucene4.7 过滤Filter(六)

先介绍下查询与过滤的区别和联系,其实查询(各种Query)和过滤(各种Filter)之间非常相似,可以 ...

Swift入门视频教程-尚学堂视频教程

最新Swift语言语法介绍,包括Swift流程控制语句、Swift各种构造函数、closure、泛型、 ...

java.lang.ClassNotFoundException: org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter的解决方案

struts2.0.x到struts 2.1.2使用的核心 过滤器是FilterDispatcher, ...

Solr4:利用Filter实现两组关键词组合查询

本文参考:Lucene4.1:利用Filter实现两组关键词组合查询 1. 需求 根据客户名称,查询 ...

Storm【实践系列-如何写一个爬虫- 对于Protocol进行的封装】

本章描述:对于Protocol的封装 packagecom.digitalpebble.storm.c ...

Filter 简单应用实例求详解

web.xml <filter> <filter-name>AdminFi ...

线性渐变-linear-gradient和滤镜opacity/filter的透明效果兼容性解决方案及其RGB/RGBA与16进制转换方法

第一篇:滤镜opacity/filter的透明效果兼容性解决方案RGB/RGBA介绍 项目中需要实现透 ...

Hadoop源码分析之RPC(Remote Procedure Call Protocol)

理解这个RPC是不是的先去理解哈动态代理 好多invoke,还有Socket网络编程 先来张eclip ...

报错说找不到abbrev这个方法,但Array有这个方法的吧?

以下是ruby-doc.org http://www.ruby-doc.org/core/class ...

最新问答

更多

获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)

我用Google搜索了一个解决方案。 “EnumDisplayModeProvider”是我自己设置网站的各种模式的枚举。 public EnumDisplayModeProvider GetDisplayModeId() { foreach (var mode in DisplayModeProvider.Instance.Modes) if (mode.CanHandleContext(HttpContext)) {

如何通过引用返回对象?(How is returning an object by reference possible?)

这相对简单:在类的构造函数中,您可以分配内存,例如使用new 。 如果你制作一个对象的副本,你不是每次都分配新的内存,而是只复制指向原始内存块的指针,同时递增一个也存储在内存中的引用计数器,使得每个副本都是对象可以访问它。 如果引用计数降至零,则销毁对象将减少引用计数并仅释放分配的内存。 您只需要一个自定义复制构造函数和赋值运算符。 这基本上是共享指针的工作方式。 This is relatively easy: In the class' constructor, you allocate m

矩阵如何存储在内存中?(How are matrices stored in memory?)

正如它在“熵编码”中所说的那样,使用Z字形图案,与RLE一起使用,在许多情况下,RLE已经减小了尺寸。 但是,据我所知,DCT本身并没有给出稀疏矩阵。 但它通常会增强矩阵的熵。 这是compressen变得有损的点:输入矩阵用DCT传输,然后量化量化然后使用霍夫曼编码。 As it says in "Entropy coding" a zig-zag pattern is used, together with RLE which will already reduce size for man

每个请求的Java新会话?(Java New Session For Each Request?)

你是如何进行重定向的? 您是否事先调用了HttpServletResponse.encodeRedirectURL()? 在这里阅读javadoc 您可以使用它像response.sendRedirect(response.encodeRedirectURL(path)); The issue was with the path in the JSESSIONID cookie. I still can't figure out why it was being set to the tomca

css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)

我认为word-break ,如果你想在一个单词中打破行,你可以指定它,这样做可以解决问题: .column { word-break:break-all; } jsFiddle演示。 您可以在此处阅读有关word-break属性的更多信息。 I think word-break, with which you can specify if you want to break line within a word, will do the trick: .column { word-break

无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)

我认为您忘记在分类时间内缩放输入图像,如train_test.prototxt文件的第11行所示。 您可能应该在C ++代码中的某个位置乘以该因子,或者使用Caffe图层来缩放输入(请查看ELTWISE或POWER图层)。 编辑: 在评论中进行了一次对话之后,结果发现在classification.cpp文件中错误地删除了图像均值,而在原始训练/测试管道中没有减去图像均值。 I think you have forgotten to scale the input image during cl

xcode语法颜色编码解释?(xcode syntax color coding explained?)

转到: Xcode => Preferences => Fonts & Colors 您将看到每个语法高亮颜色旁边都有一个简短的解释。 Go to: Xcode => Preferences => Fonts & Colors You'll see that each syntax highlighting colour has a brief explanation next to it.

在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)

你考虑过第三方拼写检查吗? 您可以将在C#中开发的自定义WinForms控件插入访问数据库吗? VB6控件怎么样? 如果你能找到一个使用第三方库进行拼写检查的控件,那可能会有效。 Have you considered a third party spell checker? Can you insert a custom WinForms controls developed in C# into an access database? What about a VB6 control? If

从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)

我有同样的问题,因为我在远程服务器上有两个图像,我需要在每天的预定义时间复制到我的本地服务器,这是我能够提出的代码... try { if(@copy('url/to/source/image.ext', 'local/absolute/path/on/server/' . date("d-m-Y") . ".gif")) { } else { $errors = error_get_last(); throw new Exception($err

从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))

我不确定我完全明白你在说什么。 你能编辑你的帖子并包含你正在做的Subversion命令/操作的特定顺序吗? 最好使用命令行svn客户端,以便容易为其他人重现问题。 如果您只是想获取文件的旧副本(即使该文件不再存在),您可以使用如下命令: svn copy ${repo}/trunk/moduleA/file1@${rev} ${repo}/trunk/moduleB/file1 其中${repo}是您的存储库的URL, ${rev}是您想要的文件的版本。 这将恢复该文件的旧版本,包括最高版本