我正在创建一个对书进行排序的react网络应用。我创建了一个redux文件,稍后将其连接到该应用程序。但是我在排序逻辑上遇到了麻烦。
我创建了一个带有减速器的商店,供用户插入书籍,另一本书用于控制执行哪种排序。我已经测试过,并且排序状态正在使用store.dispatch进行更改。但是我无法解决为什么没有按合格标准对书籍进行排序的问题。我不太确定getSortedBooks函数中是否存在逻辑问题。
//ACTIONS
//ADD BOOK
const addBook = ({ title = '', author = '', editionYear = 0} = {}) => ({
type: 'ADD_BOOK',
book: {
title,
author,
editionYear
}
});
//SORT BY
const sortBy = (order) => ({
type: 'SORT_BY',
orderBy: order
});
//book reducer
const bookReducerDefaultState = [];
const bookReducer = (state = bookReducerDefaultState, action) => {
switch(action.type) {
case 'ADD_BOOK':
return [
...state,
action.book
];
default:
return state;
};
};
//sorting reducer
const sortingReducerDefaultState = {
orderBy: ''
};
const sortingReducer = (state = sortingReducerDefaultState, action) => {
switch(action.type) {
case 'SORT_BY':
return {
...state,
orderBy: action.orderBy
};
case 'SORT_BY_TITLE':
return {
...state,
sortBy: 'title',
order: action.order
};
case 'SORT_BY_AUTHOR':
return {
...state,
sortBy: 'author',
order: action.order
}
case 'SORT_BY_EDITION_YEAR':
return {
...state,
sortBy: 'editionYear',
order: action.order
}
default:
return state;
};
}
//get sorted books
function getSortedBooks(books, orderBy) {
orderBy = Array.isArray(orderBy) ? orderBy : [orderBy];
return books.sort((a, b) => {
for (let i = 0, size = orderBy.length; i < size; i++) {
const key = Object.keys(orderBy[i])[0],
o = orderBy[i][key],
valueA = a[key],
valueB = b[key];
if(!(valueA || valueB)) {
console.error("the objects from the data passed does not have the key '" + key + "' passed on sort!");
return [];
}
if (+valueA === +valueA) {
return o.toLowerCase() === 'desc' ? valueB - valueA : valueA - valueB;
} else {
if (valueA.localeCompare(valueB) > 0) {
return o.toLowerCase() === 'desc' ? -1 : 1;
} else if (valueA.localeCompare(valueB) < 0) {
return o.toLowerCase() === 'desc' ? 1 : -1;
}
}
}
});
};
//store creation
const store = createStore(
combineReducers({
books: bookReducer,
sorting: sortingReducer
})
);
store.subscribe(() => {
const state = store.getState();
const sortedBooks = getSortedBooks(state.books, state.sorting.orderBy);
console.log(sortedBooks);
// console.log(state);
});
//input data
store.dispatch(addBook({title: 'Java How To Program', author: 'Deitel & Deitel' , editionYear: 2007 }));
store.dispatch(addBook({title: 'Patterns of Enterprise Application Architecture ', author: 'Martin Fowler' , editionYear: 2002 }));
store.dispatch(addBook({title: 'Head First Design Patterns ', author: 'Elisabeth Freeman' , editionYear: 2004 }));
store.dispatch(addBook({title: 'Internet & World Wide Web: How to Program', author: 'Deitel & Deitel' , editionYear: 2007 }));
store.dispatch(sortBy([{editionYear: 'asc'}, {title: 'desc'}]));
我希望这种结果是:
0: {title: "Patterns of Enterprise Application Architecture ", author: "Martin Fowler", editionYear: 2002}
1: {title: "Head First Design Patterns ", author: "Elisabeth Freeman", editionYear: 2004}
2: {title: "Internet & World Wide Web: How to Program", author: "Deitel & Deitel", editionYear: 2007}
3: {title: "Java How To Program", author: "Deitel & Deitel", editionYear: 2007}
但它正在返回:
0: {title: "Patterns of Enterprise Application Architecture ", author: "Martin Fowler", editionYear: 2002}
1: {title: "Head First Design Patterns ", author: "Elisabeth Freeman", editionYear: 2004}
2: {title: "Java How To Program", author: "Deitel & Deitel", editionYear: 2007}
3: {title: "Internet & World Wide Web: How to Program", author: "Deitel & Deitel", editionYear: 2007}
好像函数忽略标题:desc属性
答案 0 :(得分:0)
在getSortedBooks
中,您永远不会处理第二个sortBy
值。在每种情况下,您都可以从return
循环中for
进行第一次迭代。
我已经重构了您的代码并添加了一个有效的示例:
const books = [{
title: 'Java How To Program',
author: 'Deitel & Deitel',
editionYear: 2007
},
{
title: 'Patterns of Enterprise Application Architecture ',
author: 'Martin Fowler',
editionYear: 2002
},
{
title: 'Head First Design Patterns ',
author: 'Elisabeth Freeman',
editionYear: 2004
},
{
title: 'Internet & World Wide Web: How to Program',
author: 'Deitel & Deitel',
editionYear: 2007
}
]
function compareBy(a, b, orderBy) {
const key = Object.keys(orderBy)[0],
o = orderBy[key],
valueA = a[key],
valueB = b[key];
if (!(valueA || valueB)) {
console.error("the objects from the data passed does not have the key '" + key + "' passed on sort!");
return 0;
}
if (+valueA === +valueA) {
return o.toLowerCase() === 'desc' ? valueB - valueA : valueA - valueB;
} else {
if (valueA.localeCompare(valueB) > 0) {
return o.toLowerCase() === 'desc' ? -1 : 1;
} else if (valueA.localeCompare(valueB) < 0) {
return o.toLowerCase() === 'desc' ? 1 : -1;
}
}
return 0
}
function getSortedBooks(books, orderBy) {
orderBy = Array.isArray(orderBy) ? orderBy : [orderBy];
return books.sort((a, b) => {
let result
for (let i = 0; i < orderBy.length; i++) {
result = compareBy(a, b, orderBy[i])
if (result !== 0) {
return result
}
}
return result
})
}
console.log('title [asc]:', getSortedBooks(books, [{
title: 'asc'
}]))
console.log('author [asc]:', getSortedBooks(books, [{
author: 'asc'
}]))
console.log('editionYear [desc] author [desc] title [asc]:', getSortedBooks(books, [{
editionYear: 'desc'
}, {
author: 'desc'
}, {
title: 'asc'
}]))
console.log('editionYear [desc] author [desc] title [desc]:', getSortedBooks(books, [{
editionYear: 'desc'
}, {
author: 'desc'
}, {
title: 'desc'
}]))