Как сравнить значения из 2 массивов, чтобы отфильтровать элементы - PullRequest
0 голосов
/ 06 мая 2018

Мне очень трудно разобраться с этой проблемой. У меня есть два массива (cars и active_filters). Массив cars содержит теги html li с такими атрибутами, как тип автомобиля, количество мест, цена и т. Д. Массив active_filters содержит объекты, связанные с фильтрами, с которыми взаимодействовал пользователь, и для которых будут отображаться или скрываться автомобили.

Пример: при просмотре active filters для идентификатора data-type свойство value содержит список всех автомобильных кодов, которые пользователь хочет отобразить. Если тип данных автомобилей не найден или не совпадает с одним из этих автомобильных кодов, моя цель состоит в том, чтобы скрыть эти автомобили, добавив класс type к каждому автомобилю. Так что в этом случае к этим автомобилям должен быть добавлен класс filtered-out-by-car-type.

Я заметил, что производительность довольно медленная с тем, что у меня сейчас ниже. Кроме того, я застрял на том, как получить доступ к определенным type из активных_фильтров, связанных с найденным автомобилем. Цени любую помощь! Большое спасибо !!

Автомобили:

<li data-partner-code="EZ" data-type="XXAR" data-seats="2" data-bags="2" data-prepaid="Y" data-transmission="Automatic" data-unlimited-miles="Y" data-price="84.81" class="listing">
<li data-partner-code="AV" data-type="SFAR" data-seats="4" data-bags="2" data-prepaid="N" data-transmission="Automatic" data-unlimited-miles="Y" data-price="125.54" class="listing">
<li data-partner-code="BU" data-type="CCAR" data-seats="4" data-bags="2" data-prepaid="N" data-transmission="Automatic" data-unlimited-miles="N" data-price="65.42" class="listing">
<li data-partner-code="BU" data-type="CCAR" data-seats="4" data-bags="2" data-prepaid="N" data-transmission="Automatic" data-unlimited-miles="N" data-price="65.42" class="listing">
<li data-partner-code="FX" data-type="MCAR" data-seats="2" data-bags="1" data-prepaid="N" data-transmission="Automatic" data-unlimited-miles="N" data-price="32.00" class="listing">

Активные фильтры:

{id: "data-seats", value: "1", type: "filtered-out-by-seats"}
{id: "data-bags", value: "2", type: "filtered-out-by-bags"}
{id: "data-partner-code", value: "ET,EY,BU", type: "filtered-out-by-company"}
{id: "data-type", value: "IFAR,SFAR,PGAR,RFAR,FFAR,XXAR", type: "filtered-out-by-car-type"}

Текущий код:

cars.forEach(function(car)
{
    var found = active_filters.find(function(filter) {
        var filter_value = filter.value.split(","); // getting unique value
        for (var i=0; i<filter_value.length; i++)
        {
            if (car.attr(filter.id) === filter_value[i])
            {
                return car; // Why is this returning active_filters element instead of car?
            }
        }
    });

    // Todo: How can I access active_filters.type associated to the car that was found?
    if (!found)
    {
        car.addClass(active_filters.type); // ?
    }
});

1 Ответ

0 голосов
/ 06 мая 2018

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

Во-первых, кажется, что основная идея состоит в том, чтобы фильтровать массив cars в подмножество. Оказывается, есть метод Array только для этого, который называется, естественно, filter

const filtered_cars = cars.filter(car => {
    // This function will get passed each car in turn. Return
    // true if the car should be kept in the list, false otherwise.
});

Теперь, для каждой машины, я думаю, вы хотите проверить все активные фильтры. Если какой-либо из активных фильтров соответствует, автомобиль должен быть сохранен. Опять же, есть метод Array, в данном случае это some.

const filtered_cars = cars.filter(car => {
    return active_filters.some(filter => {
        // Within this function, we have a car variable, and a filter
        // variable. We want to return true if the car matches the
        // filter, false otherwise
    });
});

Из вашего описания следует, что каждый активный фильтр может иметь несколько значения, разделенные запятыми. Нам нужно извлечь их в массив. Мы также можем извлечь соответствующий атрибут автомобиля для фильтра.

const filtered_cars = cars.filter(car => {
    return active_filters.some(filter => {
        const values = filter.value.split(",");
        const attribute = car.getAttribute(filter.id);
        // Return true if the attribute is in the set of values
    });
});

Еще раз мы можем использовать some

const filtered_cars = cars.filter(car => {
    return active_filters.some(filter => {
        const values = filter.value.split(",");
        const attribute = car.getAttribute(filter.id);
        return values.some(value => {
            return value === attribute;
        });
    });
});

На данный момент мы уменьшили массив автомобилей только до тех элементов, которые соответствуют фильтрам, но мы не добавили тип для тех автомобилей, которые не создали фильтр. Чтобы сделать это, мы должны заменить первый some на forEach, чтобы убедиться, что мы перебираем все фильтры вместо остановки при первом совпадении. Также мы хотим добавить или удалить специальный класс в зависимости от ситуации.

const filtered_cars = cars.filter(car => {
    let keep_car = false;
    active_filters.forEach(filter => {
        const values = filter.value.split(",");
        const attribute = car.getAttribute(filter.id);
        const matched = values.some(value => {
            return value === attribute;
        });
        car.classList.toggle(filter.type, !matched);
        keep_car = keep_car || matched;
    });
    return keep_car;
});

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...