Typescript / Javascript: преобразовать массив объектов в ключ, пару значений - PullRequest
0 голосов
/ 08 апреля 2019

в моем приложении (React-typcript) У меня есть несколько документов типа

interface IDocument {id: string;  questions: IQuestion[];}

interface IQuestion {number: string;  answer: string; }

, поэтому массив документов будет выглядеть примерно так:

doscuments: IDocument[] = [
  {id: "a",
    questions: [
      { number: "1", answer: "answer1" },
        ... /* more number answer*/
    ]},
  {id: "b",
    questions: [
      { number: "1", answer: "answer1" },
        ... /* more number answer*/
    ]}
];

Теперь я хочупреобразовать его в альтернативную форму типа

interface IAlternative {
  [key: string]: string;
}

, чтобы иметь пары ключ-значение, например,

alterDocs: IAlternative = {a1:"answer1", a2:"answer2",...,b1:"answer1",...}

. Для этого у меня есть код ниже, но я не могу создать пару с doc.id+question.number в качестве ключа и question.answer в качестве значения

documents.forEach(doc:IDocument=>{
 doc.questions.forEach(question=>{
    const pair= {} // I cannot construct this pair
    alterDocs={...alterDocs,...pair}
  })
})

Ответы [ 3 ]

2 голосов
/ 08 апреля 2019

Вы можете использовать функцию Reduce, чтобы получить желаемую структуру данных.

const alterDocs = documents.reduce((total, doc: IDocument): IAlternative[] => {

  // loop through the questions and create an array of IAlternative objects
  const subDocs = doc.questions.reduce((aggregator, question: IQuestion): IAlternative[] => {

    // push the next question onto the IAlternative object
    aggregator.push({
      `${doc.id}${question.number}`: question.answer,
    });

    // return the IAlternative array
    return aggregator
  }, []);

  //  You will have an array of IAlternative documents.  Append this onto 
  //  the parent IAlternative array with concat
  total.concat(subDocs);
  return total;
}, []);
1 голос
/ 10 апреля 2019

Я обнаружил, что это было намного проще, чем я думал :) Благодаря ответам, но не было необходимости в сложных редукторах

   alterDocs: IAlternative = {}

    documents.forEach(doc=>{
    const id=doc.id;
    doc.questions.forEach(q=>{
        const num=q.number;
        const ans=q.answer;
        alterDocs[`${id}${num}`]=ans;
      })
    })

let documents = [
  {id: "A", questions: [
      { number: "1", answer: "answerA1" },
      { number: "2", answer: "answerA2" },
      { number: "3", answer: "answerA3" }
    ]
  },
  {id: "B", questions: [
      { number: "1", answer: "answerB1" },
      { number: "2", answer: "answerB2" },
      { number: "3", answer: "answerB3" }

    ]
  },
  {id: "C", questions: [
      { number: "1", answer: "answerC1" },
      { number: "2", answer: "answerC2" },
      { number: "3", answer: "answerC3" }

    ]
  }
];

let altDocs = {};

documents.forEach(doc => {
   const id = doc.id;
      doc.questions.forEach(q => {
        const num = q.number;
        altDocs[`${id}${num}`] = q.answer;
      });
    });
    
    console.log(altDocs);
1 голос
/ 08 апреля 2019

Вы можете использовать уменьшить

Здесь идея

  • Переберите arr, получите id и questions от элемента
  • Без цикла на questions добавить ключ и значение в соответствии с желаемым форматом

let arr = [
  {id: "a",
    questions: [
      { number: "1", answer: "answer1" },
        { number: "2", answer: "answer2" }
    ]},
  {id: "b",
    questions: [
      { number: "1", answer: "answer1" },
      { number: "2", answer: "answer2" }
    ]}
];

let op = arr.reduce((op,inp)=>{
  let key = inp.id
  let value = inp.questions
  value.forEach(e=>{
    op[`${key}${e.number}`] = op[`key${e.number}`] || {}
    op[`${key}${e.number}`] = e.answer
  })
  return op
},{})

console.log(op)
...