Фильтрующий массив с 1 условием массива и внешними логическими условиями - PullRequest
0 голосов
/ 27 апреля 2018

Фильтрация carArray с определенными условиями от пользователя.

Когда пользователь установит флажок red, он будет фильтровать автомобили красной краской. Когда пользователь установит флажок green, он будет фильтровать автомобили с зеленой краской. Когда пользователь установит флажки red и green, он покажет красные и зеленые автомобили. (и т. д. с N условиями пользователя)

Я использую 2 флажка для этого примера. У меня более 5 флажков в моей реальной реализации.

Я начал с логических переменных showRed, showGreen для отслеживания потребностей пользователей и массива car объекта.

[ {
       carName: xxx, 
       color: 'red'
  },
  {
       carName: yyy, 
       color: 'green'
  },
   .....
]

filteredCars = carArray.filter((car) => {
    // Problem: I tried to check for showRed and 
    // showGreen before returning but found out that I can 
    // only return once in here
    if (showRed) {
        return car.color === 'red';
    }
    if (showGreen) {
        return car.color === 'green';
    }
});

В настоящее время я сталкиваюсь с некоторыми проблемами при фильтрации с несколькими условиями пользователя.

Ответы [ 7 ]

0 голосов
/ 27 апреля 2018

Мои два цента в этом случае состоят в том, что я сгруппирую автомобили по цвету, поэтому мне не нужно фильтровать каждую машину по очереди при смене флажков.

Я бы получал автомобили проверенных цветов с карты (где ключ - это цвет, а значение - массив автомобилей этого цвета).

С другой стороны, я использовал ramda , чтобы избежать шаблонов, поскольку он уже реализует groupBy .

const cars = [{
    carName: 'xxx',
    color: 'red'
  },
  {
    carName: 'yyy',
    color: 'green'
  }
]

const carMap = R.groupBy(car => car.color, cars)

// A function to get multiple keys of a given map
// (using objects instead of Map). It will get one or 
// more arrays, and that's why I use R.flatten: to get a flat 
// array of cars of different colors
const multiMapGet = (keys, map) => R.flatten(keys.map(key => map[key]))

// The array of colors would be the checked checkbox selected
// colors
const carsOfColors = multiMapGet(['red', 'green'], carMap)

console.log(carsOfColors)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
0 голосов
/ 27 апреля 2018
let filteredCars=[];
            let filteredData = carsArray.filter(function(car){
                    if(showRed && car.color === 'red') {
                        filteredCars.push(car);
                    }
                    if(showGreen && car.color === 'green') {
                        filteredCars.push(car);
                    }
                    //any other color or filter that u want to implement can go here
            })

Фильтрованные автомобили будут содержать список автомобилей, доступных после применения всех фильтров.

0 голосов
/ 27 апреля 2018

Вот как вы можете построить свою функцию фильтра, используя метод получения, который получает значение от объекта (в данном случае цвет), и компаратор, который будет сравнивать это значение и возвращать true или false (в этом случае функция с именем hasColor частично применяется с набором цветов):

const arr = [ 
  {
    carName: "xxx", 
    color: 'red'
  },
  {
    carName: "yyy", 
    color: 'green'
  }
]
//function to get an item from an object (in this case color)
//  defaults to empty string if o or o.tags doesn't exist
const getColor = o => (o&&o.color) || ""; 

//function to compare a value, in this case a string with array of strings
//  in this case the haystack is the colors you are looking for and the needle
//  is the color of the current car
const compareSomePrimitive = (hayStack,needle) =>
  hayStack.includes(needle);
//curryable function to filter, takes 2 functions:
//  getter: to get the value to compare from the object passed into it 
//    like getColor to get color from a car
//  comparer: to compare the value 
const filterFn = getter => comparer => object =>
  comparer(getter(object))
//partially applied filterFn getting the color property from a car
const filterColor = filterFn(getColor);

//partially applied filterFn that has getter and comparer, only need to pass the car to finish
const hasColor = whatColors=>
  filterColor(
    currentColor =>
      compareSomePrimitive(whatColors,currentColor)
  );
//use hasColor filter function
console.log(
  "has color red or green",
  arr.filter(hasColor(["red","green"]))
)

//example with showRed, showGreen
const getColors = settings => {
  var colors = ["red","green"];
  if(!settings.showRed){
    colors = colors.filter(color=>color!=="red");
  }
  if(!settings.showGreen){
    colors = colors.filter(color=>color!=="green");
  }
  return colors;
};

console.log(
  "has color red or green with showRed, showGreen",
  arr.filter(hasColor(
    getColors(
      {showRed:true,showGreen:false}
    )
  ))
)
0 голосов
/ 27 апреля 2018

Использование Jquery

let selection = [];


$(".checkBox").each(function() { //you can change .checkBox to your checkBox Id.
    if ($( this ).prop("checked")){
        selection.push( $( this ).text() );
    }
})

Вы можете использовать этот фрагмент.

Затем создайте свой фильтр с помощью этого массива.

0 голосов
/ 27 апреля 2018

Быстрое предположение: return выходит из стека вызовов. Вы должны продолжить итерацию и заполнить временный массив найденными правильными записями, а затем вернуть массив. То есть выполните «жадный» поиск.

0 голосов
/ 27 апреля 2018

Почему бы не поместить нужные цвета в массив colors и проверить цвет автомобиля

filteredCars = carArray.filter(({ color }) => colors.includes(color));
0 голосов
/ 27 апреля 2018

При смене флажков вы должны создать массив проверенных цветов. Например, если отмечены red и green, создайте массив ['red', 'green']. Затем, для вашей функции фильтра, проверьте, включен ли цвет автомобиля в этот массив:

// colorsToShow = ['red', 'green']
const filteredCars = carArray.filter(({ color }) => colorsToShow.includes(color));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...