按键排序字典 - Ramda
Sort dictionary by key - Ramda
在我的程序中,我试图获取一组项目(在本例中为房间),通过一些 属性(超过 10 个座位的房间)对其进行过滤,将它们分组存储在字典中(按房间所在区域分组),然后按字典键排序。
为此,我使用以下代码
import { ascend, filter, groupBy, pipe, sort } from "ramda";
class Room {
// Number of seats in the room
public seats!: number;
// Area on site, an area can have many rooms
public area!: string;
// Name of the room
public room!: number;
}
class NamedRoomDictionary {
[index: string]: Room[];
}
const GetRoomsWithMoreThanTenSeats = (rooms: Room[]): Room[] =>
filter(room => room.seats > 10, rooms);
const GroupByArea = (rooms: Room[]): NamedRoomDictionary =>
groupBy(room => room.area, rooms);
const SortByArea = (rooms: NamedRoomDictionary): NamedRoomDictionary =>
sort(ascend(room => room.index), rooms)
const SortBigRoomsByArea = pipe(
GetRoomsWithMoreThanTenSeats,
GroupByArea,
SortByArea
);
const rooms: Room[] = [
{room: 1, area: 'A', seats: 15},
{room: 2, area: 'D', seats: 5},
{room: 3, area: 'R', seats: 8},
{room: 4, area: 'E', seats: 14},
{room: 5, area: 'A', seats: 458},
{room: 6, area: 'F', seats: 10},
{room: 7, area: 'A', seats: 4},
{room: 8, area: 'A', seats: 256},
{room: 9, area: 'D', seats: 100} ];
const sorted = SortBigRoomsByArea(rooms);
console.log(sorted)
这可以在这个 Repl.it 项目中看到并 运行。
但是,我收到以下错误。
Property 'index' does not exist on type 'Room[]'.ts(2339)
以上错误与room.index
行sort(ascend(room => room.index), rooms)
有关
Argument of type 'NamedRoomDictionary' is not assignable to parameter of type 'readonly Room[][]'.
Type 'NamedRoomDictionary' is missing the following properties from type 'readonly Room[][]': length, concat, join, slice, and 18 more.ts(2345)
上述错误与行 sort(ascend(room => room.index), rooms)
上的 rooms
有关。
可以在此处看到有效的 Repl.it。这不会对组进行排序。它只是把东西分组然后显示出来。
我对整个 typescript 语法/Ramda 库还很陌生,所以任何解决这个问题的建议都将不胜感激。
的输出
{ A:
[ { room: 1, area: 'A', seats: 15 },
{ room: 5, area: 'A', seats: 458 },
{ room: 8, area: 'A', seats: 256 } ],
E: [ { room: 4, area: 'E', seats: 14 } ],
D: [ { room: 9, area: 'D', seats: 100 } ] }
的期望输出
{ A:
[ { room: 1, area: 'A', seats: 15 },
{ room: 5, area: 'A', seats: 458 },
{ room: 8, area: 'A', seats: 256 } ],
D: [ { room: 9, area: 'D', seats: 100 } ],
E: [ { room: 4, area: 'E', seats: 14 } ] }
鉴于此列表:
[
{room: 1, area: 'A', seats: 15},
{room: 2, area: 'D', seats: 5},
{room: 3, area: 'R', seats: 8},
{room: 4, area: 'E', seats: 14},
{room: 5, area: 'A', seats: 458},
{room: 6, area: 'F', seats: 10},
{room: 7, area: 'A', seats: 4},
{room: 8, area: 'A', seats: 256},
{room: 9, area: 'D', seats: 100} ];
为了获得按 area
排序的房间列表,其中 seats >= 10
,您可以:
- 只保留
seats
>= 10 的房间
- 然后在
area
上对结果列表进行排序
const rooms = [
{room: 1, area: 'A', seats: 15},
{room: 2, area: 'D', seats: 5},
{room: 3, area: 'R', seats: 8},
{room: 4, area: 'E', seats: 14},
{room: 5, area: 'A', seats: 458},
{room: 6, area: 'F', seats: 10},
{room: 7, area: 'A', seats: 4},
{room: 8, area: 'A', seats: 256},
{room: 9, area: 'D', seats: 100} ];
const z = compose(sortBy(prop('area')), filter(propSatisfies(lte(10), 'seats')));
console.log(
z(rooms)
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {compose, sortBy, prop, filter, propSatisfies, lte} = R;</script>
要按 area
(其中 seats >= 10
)对房间进行分组,您可以
- 只保留
seats
>= 10 的房间
- 然后将结果列表分组到
area
const rooms = [
{room: 1, area: 'A', seats: 15},
{room: 2, area: 'D', seats: 5},
{room: 3, area: 'R', seats: 8},
{room: 4, area: 'E', seats: 14},
{room: 5, area: 'A', seats: 458},
{room: 6, area: 'F', seats: 10},
{room: 7, area: 'A', seats: 4},
{room: 8, area: 'A', seats: 256},
{room: 9, area: 'D', seats: 100} ];
const z = compose(groupBy(prop('area')), filter(propSatisfies(lte(10), 'seats')));
console.log(
z(rooms)
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {compose, groupBy, prop, filter, propSatisfies, lte} = R;</script>
这两个片段之间的区别在于 sortBy
与 groupBy
的使用取决于用例。
您请求的输出结构不是 Ramda 专门设计来支持的。对象在 JS 中扮演着双重角色,作为字典和记录。但是这两种类型都没有内在的顺序。 Ramda 希望将具有相同键的相同值的对象视为本质上相等。因此 R.equals({a: 1, b: 2}, {b: 2, a: 1}
产生 true
。因此,虽然您可以按 area
属性 分组,并且您可以选择对结果的(数组)键进行排序,但 Ramda 不会本质上为您排序结果对象。如果您自己订购,有一天 Ramda 函数可能会为您重新订购。 (Ramda 有时会考虑按字母顺序对对象键进行排序以处理其中的一些问题。)
但是更简单的输出结构很容易实现,其中项目被过滤然后根据它们的组排序,但仍然保存在平面数组中:
const sortBigRoomsByArea = pipe (
filter ( ({seats}) => seats > 10 ),
sortBy (prop ('area'))
)
这与 customcommander 给出的答案基本相同。
如果您想对结果进行进一步排序,比如按座位数降序排列,那么切换到 sortWith
:
是有意义的
const sortBigRoomsByArea = pipe (
filter ( ({seats}) => seats > 10 ),
sortWith ([
ascend ( prop ('area') ),
descend ( prop ('seats') )
])
)
const rooms= [{room: 1, area: 'A', seats: 15}, {room: 2, area: 'D', seats: 5}, {room: 3, area: 'R', seats: 8}, {room: 4, area: 'E', seats: 14}, {room: 5, area: 'A', seats: 458}, {room: 6, area: 'F', seats: 10}, {room: 7, area: 'A', seats: 4}, {room: 8, area: 'A', seats: 256}, {room: 9, area: 'D', seats: 100}]
console .log (
sortBigRoomsByArea (rooms)
)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
<script> const {ascend, descend, filter, pipe, prop, sortWith} = R </script>
在我的程序中,我试图获取一组项目(在本例中为房间),通过一些 属性(超过 10 个座位的房间)对其进行过滤,将它们分组存储在字典中(按房间所在区域分组),然后按字典键排序。
为此,我使用以下代码
import { ascend, filter, groupBy, pipe, sort } from "ramda";
class Room {
// Number of seats in the room
public seats!: number;
// Area on site, an area can have many rooms
public area!: string;
// Name of the room
public room!: number;
}
class NamedRoomDictionary {
[index: string]: Room[];
}
const GetRoomsWithMoreThanTenSeats = (rooms: Room[]): Room[] =>
filter(room => room.seats > 10, rooms);
const GroupByArea = (rooms: Room[]): NamedRoomDictionary =>
groupBy(room => room.area, rooms);
const SortByArea = (rooms: NamedRoomDictionary): NamedRoomDictionary =>
sort(ascend(room => room.index), rooms)
const SortBigRoomsByArea = pipe(
GetRoomsWithMoreThanTenSeats,
GroupByArea,
SortByArea
);
const rooms: Room[] = [
{room: 1, area: 'A', seats: 15},
{room: 2, area: 'D', seats: 5},
{room: 3, area: 'R', seats: 8},
{room: 4, area: 'E', seats: 14},
{room: 5, area: 'A', seats: 458},
{room: 6, area: 'F', seats: 10},
{room: 7, area: 'A', seats: 4},
{room: 8, area: 'A', seats: 256},
{room: 9, area: 'D', seats: 100} ];
const sorted = SortBigRoomsByArea(rooms);
console.log(sorted)
这可以在这个 Repl.it 项目中看到并 运行。
但是,我收到以下错误。
Property 'index' does not exist on type 'Room[]'.ts(2339)
以上错误与room.index
行sort(ascend(room => room.index), rooms)
Argument of type 'NamedRoomDictionary' is not assignable to parameter of type 'readonly Room[][]'. Type 'NamedRoomDictionary' is missing the following properties from type 'readonly Room[][]': length, concat, join, slice, and 18 more.ts(2345)
上述错误与行 sort(ascend(room => room.index), rooms)
上的 rooms
有关。
可以在此处看到有效的 Repl.it。这不会对组进行排序。它只是把东西分组然后显示出来。
我对整个 typescript 语法/Ramda 库还很陌生,所以任何解决这个问题的建议都将不胜感激。
的输出
{ A:
[ { room: 1, area: 'A', seats: 15 },
{ room: 5, area: 'A', seats: 458 },
{ room: 8, area: 'A', seats: 256 } ],
E: [ { room: 4, area: 'E', seats: 14 } ],
D: [ { room: 9, area: 'D', seats: 100 } ] }
的期望输出
{ A:
[ { room: 1, area: 'A', seats: 15 },
{ room: 5, area: 'A', seats: 458 },
{ room: 8, area: 'A', seats: 256 } ],
D: [ { room: 9, area: 'D', seats: 100 } ],
E: [ { room: 4, area: 'E', seats: 14 } ] }
鉴于此列表:
[
{room: 1, area: 'A', seats: 15},
{room: 2, area: 'D', seats: 5},
{room: 3, area: 'R', seats: 8},
{room: 4, area: 'E', seats: 14},
{room: 5, area: 'A', seats: 458},
{room: 6, area: 'F', seats: 10},
{room: 7, area: 'A', seats: 4},
{room: 8, area: 'A', seats: 256},
{room: 9, area: 'D', seats: 100} ];
为了获得按 area
排序的房间列表,其中 seats >= 10
,您可以:
- 只保留
seats
>= 10 的房间
- 然后在
area
上对结果列表进行排序
const rooms = [
{room: 1, area: 'A', seats: 15},
{room: 2, area: 'D', seats: 5},
{room: 3, area: 'R', seats: 8},
{room: 4, area: 'E', seats: 14},
{room: 5, area: 'A', seats: 458},
{room: 6, area: 'F', seats: 10},
{room: 7, area: 'A', seats: 4},
{room: 8, area: 'A', seats: 256},
{room: 9, area: 'D', seats: 100} ];
const z = compose(sortBy(prop('area')), filter(propSatisfies(lte(10), 'seats')));
console.log(
z(rooms)
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {compose, sortBy, prop, filter, propSatisfies, lte} = R;</script>
要按 area
(其中 seats >= 10
)对房间进行分组,您可以
- 只保留
seats
>= 10 的房间
- 然后将结果列表分组到
area
const rooms = [
{room: 1, area: 'A', seats: 15},
{room: 2, area: 'D', seats: 5},
{room: 3, area: 'R', seats: 8},
{room: 4, area: 'E', seats: 14},
{room: 5, area: 'A', seats: 458},
{room: 6, area: 'F', seats: 10},
{room: 7, area: 'A', seats: 4},
{room: 8, area: 'A', seats: 256},
{room: 9, area: 'D', seats: 100} ];
const z = compose(groupBy(prop('area')), filter(propSatisfies(lte(10), 'seats')));
console.log(
z(rooms)
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {compose, groupBy, prop, filter, propSatisfies, lte} = R;</script>
这两个片段之间的区别在于 sortBy
与 groupBy
的使用取决于用例。
您请求的输出结构不是 Ramda 专门设计来支持的。对象在 JS 中扮演着双重角色,作为字典和记录。但是这两种类型都没有内在的顺序。 Ramda 希望将具有相同键的相同值的对象视为本质上相等。因此 R.equals({a: 1, b: 2}, {b: 2, a: 1}
产生 true
。因此,虽然您可以按 area
属性 分组,并且您可以选择对结果的(数组)键进行排序,但 Ramda 不会本质上为您排序结果对象。如果您自己订购,有一天 Ramda 函数可能会为您重新订购。 (Ramda 有时会考虑按字母顺序对对象键进行排序以处理其中的一些问题。)
但是更简单的输出结构很容易实现,其中项目被过滤然后根据它们的组排序,但仍然保存在平面数组中:
const sortBigRoomsByArea = pipe (
filter ( ({seats}) => seats > 10 ),
sortBy (prop ('area'))
)
这与 customcommander 给出的答案基本相同。
如果您想对结果进行进一步排序,比如按座位数降序排列,那么切换到 sortWith
:
const sortBigRoomsByArea = pipe (
filter ( ({seats}) => seats > 10 ),
sortWith ([
ascend ( prop ('area') ),
descend ( prop ('seats') )
])
)
const rooms= [{room: 1, area: 'A', seats: 15}, {room: 2, area: 'D', seats: 5}, {room: 3, area: 'R', seats: 8}, {room: 4, area: 'E', seats: 14}, {room: 5, area: 'A', seats: 458}, {room: 6, area: 'F', seats: 10}, {room: 7, area: 'A', seats: 4}, {room: 8, area: 'A', seats: 256}, {room: 9, area: 'D', seats: 100}]
console .log (
sortBigRoomsByArea (rooms)
)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
<script> const {ascend, descend, filter, pipe, prop, sortWith} = R </script>