Когда я работал в предыдущей компании, было требование выполнить функцию скрининга во фронтальной части, получить все данные за один раз, а потом фильтровать по условиям. Обычно скрининг обеспечивается фоном к интерфейсу.В случае небольшого объема данных некоторые люди могут столкнуться с ситуацией скрининга фронтенда.Я написал эту статью, чтобы поделиться ею с вами.Если у вас есть какие-либо вопросы , пожалуйста, указывайте и учитесь друг у друга.
В общем, для скрининга по одному условию метод фильтрации массива может соответствовать требованиям.В этой статье основное внимание уделяется сложному скринингу при нескольких условиях, и перечислены несколько связанных точек знаний.
Здесь много 🌰🌰🌰🌰
// 这个是例子中的被筛选数组
var aim = [
{name:'Anne', age: 23, gender:'female'},
{name:'Leila', age: 16, gender:'female'},
{name:'Jay', age: 19, gender:'male'},
{name:'Mark', age: 40, gender:'male'}
]
Фильтр данных с одним условием
Фильтруйте по одному имени, используйте метод фильтра, чтобы определить, является ли имя целевым именем.
// 根据单个名字筛选
function filterByName(aim, name) {
return aim.filter(item => item.name == name)
}
// 输入 aim 'Leila' 期望输出为 [{name:'Leila', age: 16, gender:'female'}]
console.log(filterByName(aim,'leila'))
Фильтр нескольких данных с одним условием
Фильтруйте по нескольким именам. Здесь нужно использовать цикл for для обхода целевого массива, а затем использовать метод find, чтобы найти его и поместить в массив результатов. Метод find также может получить желаемый результат, даже если имя то же. Цикл for можно заменить некоторыми методами обхода массива, а код можно упростить, например, для выражения смысла.
// 根据多个名字筛选
function filterByName1(aim, nameArr) {
let result = []
for(let i = 0; i < nameArr.length; i++) {
result.push(aim.find(item => item.name = nameArr[i]))
}
return result
}
// 输入 aim ['Anne','Jay']
//期望输出为 [{name:'Anne', age: 23, gender:'female'},{name:'Jay', age: 19, gender:'male'}]
console.log(filterByName1(aim,['Leila','Jay']))
// 有BUG 改进后
Единый фильтр данных с несколькими условиями
Отфильтруйте по одному имени или одному возрасту и используйте метод фильтрации, чтобы определить взаимосвязь между условиями.
// 根据名字或者年龄筛选
function filterByName2(aim, name, age) {
return aim.filter(item => item.name == name || item.age == age)
}
console.log(filterByName2(aim,'Leila',19))
Фильтрация нескольких данных с несколькими условиями
Сначала я сделал это с тупым двойным циклом for и обнаружил, что он медленный и не дает желаемого эффекта. Конкретное ментальное путешествие слишком далеко, поэтому кратко представлен следующий алгоритм фильтрации.
Первый — запихнуть все условия фильтрации в один объект, с помощью метода keys объекта object получить имя условия фильтрации, а какое условие нужно отфильтровать, какое имя? возраст пол?
Затем используйте метод filter для фильтрации целевых данных 🌰 следующим образом⬇️
Фильтр по имени и возрасту
//根据名字和年龄多元素筛选
export function multiFilter(array, filters) {
const filterKeys = Object.keys(filters)
// filters all elements passing the criteria
return array.filter((item) => {
// dynamically validate all filter criteria
return filterKeys.every(key => {
//ignore when the filter is empty Anne
if(!filters[key].length) return true
return !!~filters[key].indexOf(item[key])
})
})
}
/*
* 这段代码并非我原创,感兴趣的可以去原作者那里点个赞
* 作者是:@author https://gist.github.com/jherax
* 这段代码里我只加了一行,解决部分筛选条件清空时候整体筛选失效的问题
*/
var filters = {
name:['Leila', 'Jay'],
age:[]
}
/* 结果:
* [{name: "Leila", age: 16, gender: "female"},
* {name: "Jay", age: 19, gender: "male"}]
*/
Например, здесь оценивается, находится ли значение имени каждого данных в массиве filter.name. Если это так, он возвращает true.Если оценивается, что filter.age является пустым массивом, он возвращает true напрямую , Получите правильные данные фильтра.
Точка знаний 1: Object.key() получает индекс массива или свойство объекта
var arr = ['a', 'b', 'c'];
console.log(Object.keys(arr));
// ["0", "1", "2"]
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.keys(obj));
// ["0", "1", "2"]
var anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj));
// ["2", "7", "100"] 猜猜为啥?
Пункт знаний 2: ложь в js
falsy : 0 , false, "", null, undefined, NaN
В суждении только 6 вышеуказанных случаев будут ложными, остальные верны
var a;
if(a!=null&&typeof(a)!=undefined&&a!=''){
//a有内容才执行的代码
}
if(!!a){
//a有内容才执行的代码...
}
Пункт знаний 3: разница между Array.every и Array.some
Насколько я понимаю, при переборе массива:
Array.everyУсловие представляет собой отношение «и», все верно истинно, а условие истинно, оно истинно, и если есть ложное, оно возвращает ложное
Array.someУсловие представляет собой отношение "или", true равно true, если одно из условий истинно, возвращает true, а если все условия ложны, возвращает false
Вот пример 🌰
// 判断每个名字都为Anne?
let dataEvery = aim.every(item => item.name === 'Anne') // false
let dataEvery = aim.some(item => item.name === 'Anne') // true
// 判断每个名字都是字符串?
let dataEvery = aim.every(item => typeof item.name === 'string') // true
let dataEvery = aim.some(item => typeof item.name === 'string') // true
Пункт знаний 4: глубокая копия и поверхностная копия массива
Недавно я участвовал в нескольких фронтенд-интервью, и один из моих любимых вопросов — глубокое копирование или поверхностное копирование. В одном вопросе рассматриваются типы данных, операции с массивами, рекурсивные алгоритмы и т. д.
Поскольку массив является ссылочным типом в js, ссылочное отношение копируется при простом копировании. При фильтрации полученных данных я не хочу влиять на исходные данные, поэтому я использую «глубокую копию», чтобы получить данные с той же структурой данных и независимо от исходных данных, вместо того, чтобы просто копировать их ссылочные отношения.
// 我常用方法,如果项目很大,不推荐
let obj1 = JSON.parse(JSON.stringify(obj))
// deepclone
function deepClone(o1, o2) {
for (let k in o2) {
if (typeof o2[k] === 'object') {
o1[k] = {};
deepClone(o1[k], o2[k]);
} else {
o1[k] = o2[k];
}
}
}
Подумайте об этом: оптимизация рекурсивных алгоритмов
Этот пункт знаний имеет мало общего с этой статьей. 😄 Извините за предыдущее заблуждение.
Это то, что я увидел в буклете Nuggets по фронтенду. Когда я говорил об алгоритме, я упомянул оптимизацию рекурсивного алгоритма. Я был удивлен, когда впервые увидел его, и я не использовал его в проект. Если интересно, можете попробовать, это сумма последовательности Фибоначчи. Можете сами набрать в браузере, и попробовать разницу в количестве операций без кеша и с кешем.
let count = 0;
function fn(n) {
let cache = {};
function _fn(n) {
if (cache[n]) {
return cache[n];
}
count++;
if (n == 1 || n == 2) {
return 1;
}
let prev = _fn(n - 1);
cache[n - 1] = prev;
let next = _fn(n - 2);
cache[n - 2] = next;
return prev + next;
}
return _fn(n);
}
let count2 = 0;
function fn2(n) {
count2++;
if (n == 1 || n == 2) {
return 1;
}
return fn2(n - 1) + fn2(n - 2);
}
Заканчивать!