Массив карты для реализации определенного типа объекта c - PullRequest
0 голосов
/ 24 марта 2020

У меня есть класс Rule следующим образом:

export class Rule {

    public text: string
    public severity: number

    constructor(
        text: string,
        severity: number,
    ) {
        this.text = text
        this.severity = severity
    }
}

Как я могу сгенерировать следующий объект incidenceRules из массива Rule?

export interface IncidenceRuleObj {
    ruleObj: Rule // The whole object
    text: string // Rule.text should go here
}

export interface IncidenceRules {
    [severity: number]: IncidenceRuleObj
}

export const incidenceRules = (rules: Rule[]): IncidenceRules => {
    return rules.map(rule => {
        // What should go here in order to return an IncidenceRules type object?
    })
}

Например, это должно вернуть ту же структуру объекта, что и в этом вопросе.

Этот возвращенный объект из incidenceRules() не должен быть "жестко закодирован", поэтому необходима итерация по объектам правил.

1 Ответ

1 голос
/ 24 марта 2020

Вы не хотите использовать .map(), так как это просто создаст другой массив с сопоставленными элементами в той же позиции, что и в исходном массиве. Вместо этого, если вы все еще хотите использовать методы функционального программирования, вы должны использовать .reduce(), который перебирает массив и накапливает из него результат. Вот один из способов сделать это, который мутирует объект результата:

const incidenceRules = (rules: Rule[]): IncidenceRules =>
    rules.reduce<IncidenceRules>(
        (a, rule) => (a[rule.severity] = { ruleObj: rule, text: rule.text }, a),
        {}
    );

Вы можете видеть, что он делает то, что я думаю, что вы хотите:

console.log(JSON.stringify(
  incidenceRules([new Rule("a", 1), new Rule("b", 2)]), undefined, 2));
/* {
  "1": {
    "ruleObj": {
      "text": "a",
      "severity": 1
    },
    "text": "a"
  },
  "2": {
    "ruleObj": {
      "text": "b",
      "severity": 2
    },
    "text": "b"
  }
}*/

Если вы не считаете мутацию приемлемой вместо этого вы можете использовать распространение объекта для создания новых объектов результатов на каждом шаге:

const incidenceRulesImmutable = (rules: Rule[]): IncidenceRules =>
    rules.reduce<IncidenceRules>(
        (a, rule) => ({ ...a, [rule.severity]: { ruleObj: rule, text: rule.text } }),
        {}
    );

Это равносильно тому же; лично я не вижу ничего плохого в использовании императива l oop:

const incidenceRulesImperative = (rules: Rule[]): IncidenceRules => {
    const ret: IncidenceRules = {};
    for (const rule of rules) {
        ret[rule.severity] = { ruleObj: rule, text: rule.text }
    };
    return ret;
}

В любом случае, надеюсь, это поможет; удачи!

Детская площадка ссылка на код

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...