Skip to content
English

稳定键合并与读取顺序 ​

策略的具体实现如下。

ts
export function defineQueryAggregation<Input, Item, Context>(
  options: QueryAggregationOptions<Input, Item, Context>,
) {
  const execute = options.execute.bind(options),
    keyFor = options.key?.bind(options),
    merge = options.merge?.bind(options);
  return Object.freeze({
    /**
     * Run every input in order.
     *
     * @param inputs - Query inputs; order determines both read order and result order.
     * @param context - Host context forwarded unchanged to `execute`, `key` and `merge`.
     * @returns The merged items and their count.
     */
    collect(
      inputs: readonly Input[],
      context: Context,
      execution: Partial<import('../structs/common.js').ExecutionContext> = {},
    ): { total: number; items: Item[] } {
      return nativeSubFlowSync(execution, 'aggregation', 'query-aggregation', () => {
        const rows: Item[] = [],
          merged = new Map<string, Item>();
        for (const input of inputs)
          for (const item of synchronous(
            execute(input, context),
            'Query aggregation must be synchronous',
          )) {
            if (!keyFor) {
              rows.push(item);
              continue;
            }
            const key = synchronous(
              keyFor!(item, input, context),
              'Aggregation keys must be synchronous',
            );
            merged.set(
              key,
              merge
                ? synchronous(
                    merge(item, merged.get(key), input, context),
                    'Aggregation merge must be synchronous',
                  )
                : item,
            );
          }
        const items = keyFor ? [...merged.values()] : rows;
        return { total: items.length, items };
      });
    },
  });
}

export function mergeByKey<Item, Key>(
  items: Iterable<Item>,
  key: (item: Item) => Key,
  select: (item: Item, previous: Item | undefined) => Item,
): Item[] {
  const values = new Map<Key, Item>();
  for (const item of items) {
    const id = key(item);
    values.set(id, select(item, values.get(id)));
  }
  return [...values.values()];
}

接口参考、使用示例与开发指南。