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

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.

相关问答

更多
  • 蒙克斯的文件是迟钝的。 一位互联网英雄写道.col访问本机mongodb驱动程序,我可以做屎。 然而,我必须再次将它包装在一个承诺中,尽管没有probs。 var sessionSeen = yield new Promise(function (resolve, reject) { users.col.aggregate([ { $match: ...
  • 在光标上调用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( {timesta ...
  • 你可以使用$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} );
  • 你的函数getTotalTeamScore正在执行mongodb聚合函数,它是异步操作。 因此它不会立即返回结果,但在聚合返回DB记录之前,您的函数将被撤消。 所以你需要使用回调。 首先修改你的getTotalTeamScore函数,如下所示: module.exports.getTotalTeamScore = function (callback) { User.aggregate([ { $group: { _id: "$team", ...
  • 我可以看到这个命令的一些问题: db.location.aggregate([ {$match : { FirstName: { $nin : [" "] } } }, {$group: {_id : "$DeviceId" } }, {$project: { "DeviceId" : 1 } } ]) $match阶段与您问题中提供的文档不匹配,因为您提供的文档具有"FirstName" : " "因此该文档将匹配$in而不是$nin 如果$match阶段更改为$in那么它将发出一个文档,分组阶段 ...
  • 这两个语句在核心API级别基本相同,即获取光标并转换结果。 然而,性能有一个“核心”差异: .forEach()将“一次一个”转换游标结果并处理它提供的迭代器函数。 .fetch()从光标“一次性”获取“数组”,这意味着它在一次命中中都是“内存中”。 所以无论如何,在从查询的光标获取“核心”操作时,实际上“更快”。 但是,不评估每个游标迭代的“表达式”可能会“稍微快一点”,因此.fetch()可能在这里赢得“小”。 当然,最大的问题是“现在一切都在记忆中”,因此需要考虑“开销”。 同样,在.fetch() ...
  • Mongo shell是一个JavaScript shell,因此支持大多数标准JavaScript方法。 您可以像在JavaScript中的任何常规对象上一样检查属性是否存在 - 使用hasOwnProperty()方法: db.testData.find({}).forEach(function(x){ if (x.hasOwnProperty('name')) { // Do something } }) Mongo shell is a JavaScript she ...
  • 引号不是问题,这只是有效的JSON。 问题是,minimongo还没有实现$。 Matt Debergalis 评论Minimongo的不完整状态 (2012年10月23日): 流行谈话最近的流量提醒我,minimongo带有一个健康的改进和扩展愿望清单。 [...] $ near,$ within和$ maxDistance。 您可能有更好的运气在您具有“真正的”mongodb访问权限的服务器中执行此操作,但如果客户端存储不具有相同的功能,我不确定它是如何工作的。 Minimongo的源代码可用 。 也许 ...
  • 您无法使用聚合管道执行此操作。 您应该了解MongoDB聚合是应用于集合的一系列特殊运算符。 当您执行聚合管道时,MongoDB将运算符彼此管道连接,即运算符的输出成为以下运算符的输入。 每个运算符的结果是一个新的文档集合。 因此,您在上面尝试实现的内容可以简单地重写为以下管道,而无需首先创建文档数组: var collection = db.collection('member'), pipeline = [ { "$match": { createdDate: currentD ...
  • mongoDbHandleLoad()包含异步代码(对MongoDB的调用),因此它会在代码到达行return JSON.stringify(docs[docs.length-1]);之前返回undefined return JSON.stringify(docs[docs.length-1]); 。 你应该使用回调或Promises来取回你的结果。 我想首先你应该研究一下Javascript中的异步代码,特别是Node.js的约定。 mongoDbHandleLoad() contains asynchr ...

相关文章

更多

最新问答

更多
  • 如何在Laravel 5.2中使用paginate与关系?(How to use paginate with relationships in Laravel 5.2?)
  • linux的常用命令干什么用的
  • 由于有四个新控制器,Auth刀片是否有任何变化?(Are there any changes in Auth blades due to four new controllers?)
  • 如何交换返回集中的行?(How to swap rows in a return set?)
  • 在ios 7中的UITableView部分周围绘制边界线(draw borderline around UITableView section in ios 7)
  • 使用Boost.Spirit Qi和Lex时的空白队长(Whitespace skipper when using Boost.Spirit Qi and Lex)
  • Java中的不可变类(Immutable class in Java)
  • WordPress发布查询(WordPress post query)
  • 如何在关系数据库中存储与IPv6兼容的地址(How to store IPv6-compatible address in a relational database)
  • 是否可以检查对象值的条件并返回密钥?(Is it possible to check the condition of a value of an object and JUST return the key?)
  • GEP分段错误LLVM C ++ API(GEP segmentation fault LLVM C++ API)
  • 绑定属性设置器未被调用(Bound Property Setter not getting Called)
  • linux ubuntu14.04版没有那个文件或目录
  • 如何使用JSF EL表达式在param中迭代变量(How to iterate over variable in param using JSF EL expression)
  • 是否有可能在WPF中的一个单独的进程中隔离一些控件?(Is it possible to isolate some controls in a separate process in WPF?)
  • 使用Python 2.7的MSI安装的默认安装目录是什么?(What is the default installation directory with an MSI install of Python 2.7?)
  • 寻求多次出现的表达式(Seeking for more than one occurrence of an expression)
  • ckeditor config.protectedSource不适用于editor.insertHtml上的html元素属性(ckeditor config.protectedSource dont work for html element attributes on editor.insertHtml)
  • linux只知道文件名,不知道在哪个目录,怎么找到文件所在目录
  • Actionscript:检查字符串是否包含域或子域(Actionscript: check if string contains domain or subdomain)
  • 将CouchDB与AJAX一起使用是否安全?(Is it safe to use CouchDB with AJAX?)
  • 懒惰地初始化AutoMapper(Lazily initializing AutoMapper)
  • 使用hasclass为多个div与一个按钮问题(using hasclass for multiple divs with one button Problems)
  • Windows Phone 7:检查资源是否存在(Windows Phone 7: Check If Resource Exists)
  • 无法在新线程中从FREContext调用getActivity()?(Can't call getActivity() from FREContext in a new thread?)
  • 在Alpine上升级到postgres96(/ usr / bin / pg_dump:没有这样的文件或目录)(Upgrade to postgres96 on Alpine (/usr/bin/pg_dump: No such file or directory))
  • 如何按部门显示报告(How to display a report by Department wise)
  • Facebook墙贴在需要访问令牌密钥后无法正常工作(Facebook wall post not working after access token key required)
  • Javascript - 如何在不擦除输入的情况下更改标签的innerText(Javascript - how to change innerText of label while not wiping out the input)
  • WooCommerce / WordPress - 不显示具有特定标题的产品(WooCommerce/WordPress - Products with specific titles are not displayed)