<commit_before>import all from 'lodash/collection/all'
import any from 'lodash/collection/any'
import compact from 'lodash/array/compact'
import contains from 'lodash/collection/contains'
import curry from 'lodash/function/curry'
import has from 'lodash/object/has'
import indexOf from 'lodash/array/indexOf'
import isArray from 'lodash/lang/isArray'
import map from 'lodash/collection/map'
import pairs from 'lodash/object/pairs'
import rest from 'lodash/array/rest'
import size from 'lodash/collection/size'
import takeWhile from 'lodash/array/takeWhile'

const checkCourseAgainstQueryBit = curry((course, [key, values]) => {
	if (!has(course, key)) {
		return false
	}

	let substring = false

	// values is either:
	// - a 1-long array
	// - an $AND, $OR, $NOT, or $XOR query
	// - one of the above, but substring

	let hasBool = indexOf(values[0], '$') === 0
	let OR  = values[0] === '$OR'
	let NOR = values[0] === '$NOR'
	let AND = values[0] === '$AND'
	let NOT = values[0] === '$NOT'
	let XOR = values[0] === '$XOR'

	if (hasBool) {
		// remove the first value from the array
		// by returning all but the first element
		values = rest(values)
	}

	if (contains(['title', 'name', 'description', 'notes', 'instructors', 'times', 'locations'], key)) {
		substring = true
	}

	let internalMatches = map(values, val => {
		// dept, gereqs, etc.
		if (isArray(course[key]) && !substring) {
			return contains(course[key], val)
		}
		else if (isArray(course[key]) && substring) {
			return any(map(course[key], item => contains(item.toLowerCase(), val.toLowerCase())))
		}
		else if (substring) {
			return contains(course[key].toLowerCase(), val.toLowerCase())
		}
		return course[key] === val
	})

	if (!hasBool) {
		return all(internalMatches)
	}

	let result = false

	if (OR)   result = any(internalMatches)
	if (NOR)  result = !any(internalMatches)
	if (AND)  result = all(internalMatches)
	if (NOT)  result = !all(internalMatches)
	if (XOR)  result = compact(internalMatches).length === 1

	return result
})

/**
 * Checks if a course passes a query check.
 *
 * @param {Object} query - the query object that comes out of buildQueryFromString
 * @param {Course} course - the course to check
 * @returns {Boolean}
 */
const checkCourseAgainstQuery = curry((query, course) => {
	let kvPairs = pairs(query)
	let matches = takeWhile(kvPairs, checkCourseAgainstQueryBit(course))

	return size(kvPairs) === size(matches) && all(matches)
})

export default checkCourseAgainstQuery<commit_msg>remove use of _.curry from checkCourseAgainstQuery<commit_after>import all from 'lodash/collection/all'
import any from 'lodash/collection/any'
import compact from 'lodash/array/compact'
import contains from 'lodash/collection/contains'
import has from 'lodash/object/has'
import indexOf from 'lodash/array/indexOf'
import isArray from 'lodash/lang/isArray'
import map from 'lodash/collection/map'
import pairs from 'lodash/object/pairs'
import rest from 'lodash/array/rest'
import size from 'lodash/collection/size'
import takeWhile from 'lodash/array/takeWhile'

const checkCourseAgainstQueryBit = course => ([key, values]) => {
	if (!has(course, key)) {
		return false
	}

	let substring = false

	// values is either:
	// - a 1-long array
	// - an $AND, $OR, $NOT, or $XOR query
	// - one of the above, but substring

	let hasBool = indexOf(values[0], '$') === 0
	let OR  = values[0] === '$OR'
	let NOR = values[0] === '$NOR'
	let AND = values[0] === '$AND'
	let NOT = values[0] === '$NOT'
	let XOR = values[0] === '$XOR'

	if (hasBool) {
		// remove the first value from the array
		// by returning all but the first element
		values = rest(values)
	}

	if (contains(['title', 'name', 'description', 'notes', 'instructors', 'times', 'locations'], key)) {
		substring = true
	}

	let internalMatches = map(values, val => {
		// dept, gereqs, etc.
		if (isArray(course[key]) && !substring) {
			return contains(course[key], val)
		}
		else if (isArray(course[key]) && substring) {
			return any(map(course[key], item => contains(item.toLowerCase(), val.toLowerCase())))
		}
		else if (substring) {
			return contains(course[key].toLowerCase(), val.toLowerCase())
		}
		return course[key] === val
	})

	if (!hasBool) {
		return all(internalMatches)
	}

	let result = false

	if (OR)   result = any(internalMatches)
	if (NOR)  result = !any(internalMatches)
	if (AND)  result = all(internalMatches)
	if (NOT)  result = !all(internalMatches)
	if (XOR)  result = compact(internalMatches).length === 1

	return result
}

/**
 * Checks if a course passes a query check.
 *
 * @param {Object} query - the query object that comes out of buildQueryFromString
 * @param {Course} course - the course to check
 * @returns {Boolean}
 */
const checkCourseAgainstQuery = query => course => {
	let kvPairs = pairs(query)
	let matches = takeWhile(kvPairs, checkCourseAgainstQueryBit(course))

	return size(kvPairs) === size(matches) && all(matches)
}

export default checkCourseAgainstQuery
{'fraction_non_alphanumeric': 0.14509961762930168, 'fraction_numerical': 0.0036224592473334677, 'mean_word_length': 4.281615302869288, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6634551', 'n_tokens_mistral': 1743, 'n_tokens_neox': 1635, 'n_words': 488}