В настоящее время я создаю приложение со списком в реальном времени. вид списка как на картинке ниже:

Этот список будет обновляться в реальном времени при срабатывании одного из следующих действий:
Поэтому я хочу отсортировать этот список по двум условиям:
Данные этого списка контролируются этими редукторами:
export const data = createReducer(
{},
{
[ CONVERSATIONS_RECEIVE ]: ( state, { conversations } ) => {
return reduce(
conversations,
( memo, conversation ) => {
const { id } = conversation.data;
if ( memo === state ) {
memo = { ...memo };
}
memo[ id ] = conversation;
return memo;
},
state
);
},
[ RECEIVED_PENDING_MESSAGE ]: ( state, { data } ) => {
if ( !data || !data.conversation_id in state ) return state;
return update( state, {
[ data.conversation_id ]: { data: { $merge: { snippet: data.message, updated_time: data.created_time } } }
} )
},
[ RECEIVED_CONVERSATION_SEEN ]: ( state, { data } ) => {
if ( !data || !data.conversation_id in state ) return state;
return update( state, {
[ data.conversation_id ]: { data: { $merge: { seen: true } } }
} )
},
[ RECEIVED_CONVERSATION_UNSEEN ]: ( state, { data } ) => {
if ( !data || !data.conversation || !data.conversation.id in state ) return state;
return update( state, {
[ data.conversation.id ]: { data: { $merge: { seen: false } } }
} )
},
}
);
export function keys( state = [], action ) {
switch ( action.type ) {
case CONVERSATIONS_RECEIVE:
if ( !action.conversations || !action.conversations.length ) return state;
return state.concat( action.conversations.map( conversation => conversation.data.id ) );
default:
}
return state;
}
export default combineReducers( {
keys,
data,
isRequesting,
} );
Данные списка, отображаемые массивом ключей:
[
"id_1",
"id_2",
//....
]
и данные:
[
{
"data": {
"can_comment": false,
"can_hide": false,
"can_like": false,
"can_reply": true,
"can_reply_privately": false,
"comment_id": "",
"id": "hbiocjgwxpncbnja8a3rra4oke",
"is_hidden": false,
"is_private": false,
"last_seen_by": "ckj7mny56jrmir4df8h466uk7a",
"message": "",
"page_id": "1651651651651651",
"post_id": "",
"private_reply_conversation": "null",
"scoped_thread_key": "t_1221211454699392",
"seen": true,
"snippet": "? [ TRI ÂN VÀNG-NGÀN ƯU ĐÃI ] ?\nMiễn phí ship tận nhà ???\nChỉ còn 350k trọn bộ COMBO 3 sản phẩm tuyệt vời cho chị em và các bé nhà mình : \n? Vòng tay chỉ đỏ kim vàng đính đá topaz được nhập từ Thái Lan \n? Dây chuyền hồ ly hợp mệnh \n? Vòng tay dâu tằm cho bé \nKhuyến mại chỉ áp dụng với những khách hàng đáng yêu nhận được tin nhắn này.Nhanh tay để lại SỐ ĐIỆN THOẠI để được thỉnh bộ sản phẩm với giá siêu khuyến mại này Chị Chị Hai nha ???",
"type": "message",
"unread_count": 0,
"updated_time": "2018-12-07T12:00:21+0000"
},
"tags": [],
"from": {
"id": "1223645637789307",
"name": "Chị Hai"
}
},
{
"data": {
"can_comment": false,
"can_hide": false,
"can_like": false,
"can_reply": true,
"can_reply_privately": false,
"comment_id": "",
"id": "7oemjmkpxidi7cgk99ggbdamdw",
"is_hidden": false,
"is_private": false,
"last_seen_by": "ckj7mny56jrmir4df8h466uk7a",
"message": "",
"page_id": "1651651651651651",
"post_id": "",
"private_reply_conversation": "null",
"scoped_thread_key": "t_279998559200944",
"seen": true,
"snippet": "Giá hơi cao",
"type": "message",
"unread_count": 0,
"updated_time": "2018-12-07T12:00:19+0000"
},
"tags": [],
"from": {
"id": "280004999200300",
"name": "Chung Ngoc"
}
},
// ..... other items
]
Я пытался:
function mysortfunction(a, b) {
// always sort by updated_time first
if ( a.data.updated_time > b.data.updated_time ) return 1;
if ( a.data.updated_time <= b.data.updated_time ) return -1;
// if BOTH a.seen == false AND b.seen == false, we'll sort a & b by updated_time
if ( !a.data.seen && !b.data.seen ) {
if ( a.data.updated_time > b.data.updated_time ) return 1;
if ( a.data.updated_time <= b.data.updated_time ) return -1;
}
return 0;
}
Может ли кто-нибудь сказать мне, как лучше всего отсортировать этот список на основе моих условий выше, большое спасибо!
Пожалуйста, взгляните на мой другой ответ. Это дает образец того, как обрабатывать динамические дочерние элементы из магазина. Это может дать вам полезные данные: stackoverflow.com/questions/53189290/…
@ DoğancanArabacı: извините, я отредактировал свой вопрос, чтобы показать, что я пробовал!



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я не читал четко весь ваш код, но вы можете переупорядочить свой список только с помощью функций javascript, вы будете использовать метод sort () для сортировки всего вашего списка по updated_time и просмотренному или not_seen, вам нужно добавить функцию для метода сортировки , но единственная проблема заключается в том, что переданной функции для сравнения требуется значение типа int в качестве результата, см. их эта ссылка. так, чтобы сделать трюк, при выполнении сравнения, если его сообщение не море, добавьте, например, к UPDATED_TIME +1000000000. И так все невидимые сообщения будут первыми, и все ваши сообщения сортируются с помощью одной функции
Пара комментариев; 1. Это редуктор redux, поэтому вы не хотите мутировать, прежде чем вы сможете использовать функцию мутации sort, вам нужно сделать копию, например: arr.slice().sort(... 2. Даты представляют собой строки дат ISO, поэтому вы можете использовать сравнение строк: a.localeCompare(b) . 3. Если вы хотите выполнить сортировку по нескольким столбцам, вы можете использовать массив функций сравнения и сделать так, чтобы более ранние функции имели более высокий приоритет (запускать более позднюю функцию только в том случае, если текущая функция возвращает 0). Полный код см. В моем ответе.
да, говоря от имени mutatung, мы также можем использовать оператор распространения, я не хочу говорить о том, что он использует, или, если это сокращение или нет, я просто не хотел предложить ему способ сортировки, вот и все. И когда я ответил, он не указал формат данных, поэтому я просто предположил, что это была метка времени, и если это была метка времени, я дал ему более простую и ленивую вещь, чтобы провести сравнение без необходимости использовать массив функция сравнения. Спасибо за ваш комментарий
Проблема, с которой я столкнулся с решением UPDATED_TIME +1000000000 для сортировки по невидимому, а затем по времени обновления, заключается в том, что ваша функция сортировки делает слишком много, функции должны реализовывать только одну вещь, и если функция делает больше, чем это, она должна вызывать другие функции, которые реализуют это или вы получите функции, которые нельзя использовать повторно и комбинировать с такими именами, как sortByUnseenAndThenByDate. Если вы видите функции с такими именами, которые реализуют что-то, а не вызывают другие функции, значит, вы делаете что-то не так.
Нет, вы не поняли функцию, я не буду сортировать по невидимым, а затем обновлять, я буду сортировать один и только один раз, потому что при добавлении +1000000000 к UPDATED_TIME к невидимым элементам, когда вы выполняете сортировку, у вас автоматически будет неотправленное сообщение вверху, остальные внизу и, конечно же, все отсортированные элементы. В любом случае спасибо за ваши рекомендации
Вы можете отсортировать по нескольким значениям следующим образом:
const data = [
{ seen: true, updated_time: 'A' },
{ seen: true, updated_time: 'A' },
{ seen: false, updated_time: 'A' },
{ seen: false, updated_time: 'A' },
{ seen: false, updated_time: 'B' },
];
//compare booleans, returns -1,0 or 1
const compareSeen = (direction) => (a, b) =>
a.seen === b.seen
? 0
: a.seen
? -1 * direction
: 1 * direction;
//compare strings, returns -1, 0 or 1
const compareDate = (direction) => (a, b) =>
a.updated_time.localeCompare(b);
//pass array of compare functions and return a function that takes
// a and b and keeps using compare functions until one of them returns non zero
const createSort = (comparers = []) => (a, b) =>
comparers.reduce(
(result, compareFn) =>
result === 0 ? compareFn(a, b) : result,
0,
);
console.info(
data
.slice() //sort will mutate, we don't want that so we make a copy first
.sort(createSort([compareSeen(-1), compareDate(1)])),
);Если у вас есть время ISO из разных часовых поясов, вы не можете использовать сравнение строк, но должны сначала сопоставить строки даты с числами, а затем сопоставить их обратно:
const data = [
{ seen: true, updated_time: '2018-12-07T12:00:21+0000' },
{ seen: true, updated_time: '2018-12-07T12:00:21+0000' },
{ seen: false, updated_time: '2018-12-07T12:00:21+0000' },
{ seen: false, updated_time: '2018-12-07T12:00:21+0000' },
{ seen: false, updated_time: '2018-12-07T12:00:21+0100' },
];
//compare booleans, returns -1,0 or 1
const compareSeen = (direction) => (a, b) =>
a.seen === b.seen
? 0
: a.seen
? -1 * direction
: 1 * direction;
//compare numbers, returns negative number, 0 or positive number
const compareDate = (direction) => (a, b) =>
(a.updated_time - b.updated_time) * direction;
//pass array of compare functions and return a function that takes
// a and b and keeps using compare functions until one of them returns non zero
const createSort = (comparers = []) => (a, b) =>
comparers.reduce(
(result, compareFn) =>
result === 0 ? compareFn(a, b) : result,
0,
);
console.info(
data
.map((item) => ({
...item,
updated_time: new Date(item.updated_time).getTime(),
})) //map already copied data so sort will not mutate it
.sort(createSort([compareSeen(-1), compareDate(-1)]))
.map((item) => ({
...item,
updated_time: new Date(
item.updated_time,
).toISOString(),//note: now you have strings in UTC/Zulu time
})),
);Большое вам спасибо! Ваш ответ почти исправляет мой случай, за исключением того, что эти элементы не видны (visible = true), этот фрагмент не сортирует все элементы, если они видны (visible = true)
@Enesy, вы уверены, что свойство seen всегда истинно или ложно, а не undefined, null или 0? createSort([compareSeen(-1), compareDate(-1)]) означает, что он будет сортировать элементы с seen на ложный кулак (если вы используете compareSeen(1), сначала будет истина). Если оба видимых элемента одинаковы, то сначала выполняется сортировка по самой высокой дате (compareDate (1) сначала помещает самую низкую дату).
вы пробовали что-нибудь, чтобы их отсортировать?