在我的程序中,我尝试获取一组项目(在这种情况下为房间),通过某些属性(在其中拥有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项目中看到并运行它。
但是,我遇到以下错误。
类型“ Room []”上不存在属性“索引”。ts(2339)
上述错误与room.index
行上的sort(ascend(room => room.index), rooms)
不能将类型“ NamedRoomDictionary”的参数分配给“只读Room [] []”类型的参数。 类型“ NamedRoomDictionary”缺少类型“只读Room [] []”的以下属性:长度,连接,连接,切片和18个以上。ts(2345)
上述错误与rooms
行上的sort(ascend(room => room.index), rooms)
有关。
在这里可以看到有效的Repl.it。这不会对组进行排序。它只会将事物分组,然后显示它们。
对于整个打字稿语法/ 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 } ] }
所需的sorting repl.it输出
{ 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 } ] }
答案 0 :(得分:3)
给出此列表:
[
{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
的使用取决于使用情况。
答案 1 :(得分:2)
您所要求的输出结构不是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>