Использование фильтра по векторам - PullRequest
0 голосов
/ 15 сентября 2018

Я пытаюсь использовать функцию filter над вектором с именем dataset, который определен следующим образом:

AK,0.89,0.98
AR,0.49,0.23
AN,0.21,0.78
...

И я хочу получить все значения, которые содержат определенную строку,что-то вроде этого:

(filter (contains "AK") dataset)

Что вернет:

AK,0.89,0.98

Возможно ли это сделать с помощью функции фильтра?Я уже перебираю вектор с помощью доза, но мне нужно использовать filter в какой-то момент в моем коде.Спасибо:)

1 Ответ

0 голосов
/ 16 сентября 2018

Основной ответ - да, вы можете использовать фильтр для этого.Фильтр ожидает функцию предиката, т.е. функцию, которая возвращает истину или ложь.Функция фильтра перебирает элементы в коллекции, которую вы передаете, и передает каждый элемент из этой коллекции в предикат.То, что вы делаете внутри функции предиката, полностью зависит от вас (хотя вы должны избегать побочных эффектов).Фильтр соберет все элементы, в которых предикат вернул true, в новую ленивую последовательность.

По сути, у вас есть (длинная форма)

(filter (fn [element] 
         ; some test returning true/fals) col)

, где col - это ваша коллекция.Результатом будет LAZY SEQUENCE элементов, где функция предиката вернула true.Важно понимать, что такие вещи, как фильтр и карта, возвращают ленивые последовательности и знают, что это на самом деле означает.

Критическим моментом для понимания является структура вашей коллекции.В своем описании вы указали

Я пытаюсь использовать функцию фильтра для вектора, называемого набором данных, который определен следующим образом:

AK, 0,89,0,98 AR, 0,49,0.23АН, 0,21,0,78 ...

К сожалению, ваше описание немного двусмысленно.Если ваша структура набора данных на самом деле является вектором векторов (а не просто вектором), то все очень просто.Это потому, что это будет означать, что каждый «элемент», переданный в функцию предиката, будет одним из ваших «внутренних» векторов.Реальное определение более точно представляется как

[
 [AK,0.89,0.98]
 [AR,0.49,0.23]
 [AN,0.21,0.78]
 ...
]

. То, что будет передано предикату, - это вектор из 3 элементов.Если вы просто хотите выбрать все векторы, где первым элементом является «AK», тогда функция предиката может быть такой простой, как

(fn [el]
 (if (= "AK" (first el))
   true;
   false))

, поэтому полная строка будет выглядеть примерно так:

(filter (fn [el]
         (if (= "AK" (first el))
           true
           false)) [[AK 0.89 0.98] [AR 0.49 0.23] [AN 0.21 0.78]])

и это только начало и очень многословная версия.Есть много вещей, которые вы можете сделать, чтобы сделать это еще короче, например:

(filter #(= "AK" (first %)) [..])

Если, с другой стороны, у вас действительно есть только один вектор, то все становится немного сложнее, потому что вам нужно как-то сгруппироватьценности.Это можно сделать с помощью функции разделения, чтобы разбить ваш вектор на группы по 3 элемента, прежде чем передавать их на фильтрацию, например,

(filter pred (partition 3 col))

, которая будет группировать элементы вашего исходного вектора в группы по 3 и передавать каждыйгруппа к предикатной функции.Вот тут-то и вступает в действие настоящая мощь карт, фильтров, сокращений и т. Д. - вы можете преобразовывать данные, передавая их через конвейер функций, каждая из которых каким-то образом манипулирует данными, и в результате появляется конечный результат.

Ключевым моментом является понимание того, какой фильтр (и другие подобные функции, такие как map или Reduce) будут понимать как «элемент» в вашей коллекции входных данных.По сути, это то же самое, что будет возвращено «первым», вызванным в коллекции.Это то, что передается функции предиката в fileter.

Здесь много предположений.Одним из основных является то, что ваши данные строго упорядочены, т.е. значение, которое вы хотите проверить, всегда является первым элементом в каждой группе.Если это не так, то нужно будет проделать дополнительную работу.Аналогично, мы предполагаем, что данные всегда находятся в группах по 3. Если это не так, тогда потребуются другие подходы.

...