使用带有多个参数的谓词进行过滤

时间:2017-08-27 09:46:36

标签: list haskell filter

我有一个需要根据谓词函数过滤的项目列表。谓词函数需要多个参数才能成功返回结果。

这是我的函数类型声明,对于需要返回已过滤列表的函数:

^ // start of line \+ // a plus (?=\d{8,15}$) // look ahead and assert 8 to 15 digits must match (?: // grouped alternation (uncaptured) 32|33|49|91|352 // alternations ) // end of group \d+ // 1 or more digits $ // end of line

myFilter :: Int -> [[String]] -> [String] -> [[String]]是需要过滤的列表,是人名的列表。人名称表示如下[[String]]

["FirstName", "MiddleName", "LastName"]是个人的名称,例如[String]

我需要的是过滤掉所有名称至少不具有与个人名称相同的名称的名称的所有名称。

例如,如果我打电话

["Bob", "Jane", "Alice"]

我会得到

myFilter 2 [["a", "b", "c"],["d", "e", "f"]] ["a", "f", "b"]因为[["a", "b", "c"]]["d", "e", "f"]没有至少2个共同名称。

我计划将此作为更大程序的一部分,允许用户管理人员列表。该程序的一个功能是按名称搜索,根据用户输入的整数参数返回所有名称匹配的人员列表。

我知道["a", "f", "b"]函数,但似乎谓词函数只应该是filter类型。正如您所看到的,我的谓词更复杂。

2 个答案:

答案 0 :(得分:1)

尝试稍微移动一下参数:

myFilter :: Int -> [String] -> [[String]] -> [[String]]

如果我正确理解了问题,您希望过滤[[String]]并返回[[String]]。这与filter非常吻合,filter :: (a -> Bool) -> [a] -> [a] 的类型为:

a

具体而言,在这种情况下,[String][String] -> Bool,因此现在需要一个类型为pred :: Int -> [String] -> [String] -> Bool 的函数。

但是,您确实需要更多数据:匹配数和要搜索的名称,因此编写一个也采用这些参数的函数:

pred

现在,您可以使用要搜索的值部分应用 (pred 2 ["a", "f", "b"]),例如[String] -> Bool。该函数的类型为filter,符合myFilter i target names = filter (pred i target) names 的要求。

换句话说,你应该能够写出这样的东西:

pred

如果您愿意,可以使用myFilter关键字或where语法在let..in函数中定义<!DOCTYPE html> <html> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"> </script> <body> <div ng-app="myApp" ng-controller="myCtrl"> <form ng-submit="evaluate(configvalue2)" id="submitanswer" method="POST" > <div> <div ng-repeat="x in questions[0]">Ques No.{{questions[0].indexOf(x)+1}} <br> <span class="col-lg-12 col-md-12 col-sm-12 col-xs-12">{{x.configvalue1}} </span><br> <div ng-repeat="y in questions[1]"> <div ng-if="y.configvalue2==x.id"> <input ng-model='configvalue2' type="radio" value=" {{y.configvalue3}}" name="{{y.configvalue2}}" >{{y.configvalue1}} </div> </div> <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12"><hr></div> </div> </div> <div> <span> <input type="submit" value="Submit"> </span> </div> </form> </div> <script> var app = angular.module('myApp', []); app.controller('myCtrl', function($scope) { $scope.evaluate = function(result){ console.log("submitted value",result); } $scope.questions = [[{id:1,configvalue1:'myquestionno.1'}, {id:2,configvalue1:'myquestionno.2'}], [{configvalue2:1,configvalue1:'options1',configvalue3:1}, {configvalue2:1,configvalue1:'options2',configvalue3:2}, {configvalue2:1,configvalue1:'options3',configvalue3:3}, {configvalue2:1,configvalue1:'options4',configvalue3:4}, {configvalue2:2,configvalue1:'options1',configvalue3:1}, {configvalue2:2,configvalue1:'options2',configvalue3:2}, {configvalue2:2,configvalue1:'options3',configvalue3:3}, {configvalue2:2,configvalue1:'options4',configvalue3:4} ]]; }); </script> </body> </html>

答案 1 :(得分:0)

我猜你可以这样做;

myFilter :: Int -> [[String]] -> [String] -> [[String]]
myFilter n ass bs = filter (\as -> n <= length (filter (True ==) ((==) <$> as <*> bs))) ass

*Main> myFilter 2 [["a", "b", "c"],["d", "e", "f"]] ["a", "f", "b"]
[["a","b","c"]]

因此as[[String]]列表的每个项目。

(==) <$> as <*> bs)部分就像; (==) <$> as会将as转换为类似[(=="a"), (=="b"), (=="c")]的应用列表仿函数,然后我们会将应用中的每个函数应用于bs的每个项目[(=="a"), (=="b"), (=="c")] <*> ["a", "f", "b"],结果{ {1}}我们会过滤True值并检查长度以查看它是否为[True,False,False,False,False,True,False,False,False]

我希望很清楚。