Метод ES6 Array filter() работает не так, как ожидалось

#javascript #arrays #filter #es6-promise

#javascript #массивы #Фильтр #es6-обещание

Вопрос:

У меня есть массив объектов (блюд), которые необходимо отсортировать в соответствии с их категориями.

У меня есть набор предопределенных категорий, которые делятся на три основные группы. Если блюдо принадлежит к группе 1, оно должно появиться в начале массива. Если он принадлежит к группе 2, он должен отображаться в середине, а если он принадлежит к группе 3, он должен быть в конце. [см. Код].

Я решил взять исходный массив, создать три отдельных массива, каждый из которых содержит отфильтрованные результаты (в соответствии с группой), а затем снова объединить их.

Вот мой код (categorySort здесь является основной функцией):

 const CAT1 = ["main dish", "combo", "meal", "pasta", "pizza"];
const CAT2 = ["sandwiches", "burgers"];
const CAT3 = ['appetizers','salad','soup','frozen','healthy','catering', 'undefined'];

function belongToCategory(dishCategory, categoryArray){
    categoryArray.forEach(cat => {
        if(cat.localeCompare(dishCategory.toLowerCase()) === 0)
            console.log(`DISH ${dishCategory.toLowerCase()} BELONGS TO A CERTAIN CATEGORY ${cat}`) //dishes are being checked properly
            return true
    })
    return false
}

export const categorySort = (dishArray) => {
    let cat1Array = dishArray.filter(dish => belongToCategory(dish.category, CAT1)); 
    let cat2Array = dishArray.filter(dish => belongToCategory(dish.category, CAT2)); 
    let cat3Array = dishArray.filter(dish => belongToCategory(dish.category, CAT3)); 

    //debuggining: 
    console.log('array1');
    console.log(cat1Array);
    console.log('array2');
    console.log(cat2Array);
    console.log('array3');
    console.log(cat3Array);
    //all of the above arrays are empty
    
    return [...cat1Array, ...cat2Array, ...cat3Array];
}

//example of dishArray:
dishArray = [
  {name: 'Hummus', category: 'Appetizers'}, 
  {name: 'Mansaf', category: 'Main Dish'}, 
  {name: 'Cheese Burger', category: 'Burgers'}, 
  {name: 'Fattoush', category: 'Salad'}, 
  {name: 'Pepperoni Pizza', category: 'Pizza'}, 
  {name: 'Shawarma', category: 'Sandwiches'}, 
]
 

Однако я думаю, что я что-то упускаю из виду в том, как работает метод filter, потому что, хотя я правильно проверяю, относится ли блюдо к категории, метод filter возвращает пустой массив.

Я могу заставить это работать по-другому, но я был бы признателен, если кто-нибудь скажет мне, почему этот код не работает. Спасибо.

Ответ №1:

Ваш return true in forEach возвращает результат обратного forEach вызова, а не belongToCategory функции. for...of Вместо этого используйте цикл:

 function belongToCategory(dishCategory, categoryArray){
    for (const cat of categoryArray) {
        if(cat.localeCompare(dishCategory.toLowerCase()) === 0) {
            console.log(`DISH ${dishCategory.toLowerCase()} BELONGS TO A CERTAIN CATEGORY ${cat}`) //dishes are being checked properly
            return true
        }
    }
    return false
}
 

Также следует отметить, что это можно просто сделать с помощью .some :

 function belongToCategory(dishCategory, categoryArray){
    return categoryArray.some(cat => cat === dishCategory.toLowerCase());
}
 

Или, поскольку вы проверяете равенство, даже .includes :

 function belongToCategory(dishCategory, categoryArray){
    return categoryArray.includes(dishCategory.toLowerCase());
}