skip to Main Content

I have below sample data array of object and submittedValue object. The data array of object is constant it won’t change but submitttedValue object will change as user proceed with the answer. I have put below desired result need to extract from data array of object and submittedValue object. Please help me out if you have any solution for this.

const data = [{
  id: "Q1",
  state: "Test 1",
  answers: [
    { id: "Q1A1", text: "Yes" },
    { id: "Q1A2", text: "No" },
  ],
}, {
  id: "Q2",
  state: "Test 2",
  answers: [
    { id: "Q2A1", text: "Yes" },
    { id: "Q2A2", text: "No" },
  ],
}];

const submittedValue = {
  Q1: {
    Q1A1: "Yes",
  },
  Q2: {
    Q2A2: "No",
  },
};

How do I get the below desired result by comparing above data array of object with submittedValue object ?

// Expected outcome

const result = [
  { state: "Test 1", answer: "Yes" },
  { state: "Test 2", answer: "No" },
];

3

Answers


  1. If entries of submittedValue are guaranteed to have exactly 1 property with the answer, you can access it by simply using Object.values(submittedValue[id])[0].

    const data = [{
        id: "Q1", state: "Test 1",
        answers: [
            { id: "Q1A1", text: "Yes" },
            { id: "Q1A2", text: "No" }
        ]
    }, {
        id: "Q2", state: "Test 2",
        answers: [
            { id: "Q2A1", text: "Yes" },
            { id: "Q2A2", text: "No" }
        ]
    }, {
        id: "Q3", state: "Test 3",
        answers: [
            { id: "Q3A1", text: "Yes" },
            { id: "Q3A2", text: "No" }
        ]
    }];
    
    const submittedValue = {
        Q1: { Q1A2: "Yes" },
        Q2: { Q2A2: "No" }
    };
    
    // Process data using Array.map and Array.filter
    function processData1 (data, submittedValue) {
        return data.map(({id, state}) => {
            let entry = submittedValue[id];
            return entry? { state: state, answer: Object.values(entry)[0] }: null;
        }).filter(object => object);
    }
    
    // Process data using for loop
    function processData2 (data, submittedValue) {
        let result = [];
        for (let i = 0; i < data.length; i++) {
            let {id, state} = data[i];
            let entry = submittedValue[id];
            if (entry) {
                result.push({ state: state, answer: Object.values(entry)[0] });
            }
        }
        return result;
    }
    
    console.log(processData1(data, submittedValue));
    console.log(processData2(data, submittedValue));
    Login or Signup to reply.
  2. const data = [
    {
    id: 'Q1',
    state: 'Test 1',
    answers: [{id: "Q1A1", 'text': 'Yes'},{id: "Q1A2", 'text': 'No'}]
    },
    {
    id: 'Q2',
    state: 'Test 2',
    answers: [{id: "Q2A1", 'text': 'Yes'},{id: "Q2A2", 'text': 'No'}]
    },
    ];
    
    const submittedValue = {
        Q1: {
            Q1A2: "Yes",
        },
        Q2: {
            Q2A2: "No",
        },
    };
    
    let result = Object.keys(submittedValue).map((value) => {
      // First let's find correct question inside data
      let currentQuestion = data.find(question => value === question.id)
      
      // Now check for the current answer
      let givenAnswer = submittedValue[value]
      
      // Extract the text from given answer
      let textAnswer = Object.values(givenAnswer)[0]
      
      // Finally return the result
      return {state: currentQuestion.state, answer: textAnswer}
    })
    
    console.log(result)
    Login or Signup to reply.
  3. From the provided data structure, …

    const data = [{
      id: 'Q1',
      state: 'Test 1',
      answers: [
        { id: 'Q1A1', text: 'Yes' },
        { id: 'Q1A2', text: 'No' },
      ],
    }, {
      id: 'Q2',
      state: 'Test 2',
      answers: [
        { id: 'Q2A1', text: 'Yes' },
        { id: 'Q2A2', text: 'No' },
      ],
    }];
    

    … the submitted value …

    const submittedValue = {
      Q1: { Q1A1: 'Yes' },
      Q2: { Q2A2: 'No' },
    };
    

    … and the expected result …

    const result = [
      { state: 'Test 1', answer: 'Yes' },
      { state: 'Test 2', answer: 'No' },
    ];
    

    … it is obvious that one needs the data just for looking up the test name which is a data-item’s state-value and becomes a result-item’s state-value as well … const result = [ { state: 'Test 1', ... }, ... ];.

    As for any result-item’s answer-value, it has to be extracted from each related submitted value’s single nested property, because in the latter lays the truth and not within the data structure.

    Thus, in order to come up with the most efficient approach for retrieving any submitted value’s test name, one does reduce the data array into an object-based lookup-table where one maps its state/test-name by its id where the latter is the key and the former is the value … e.g. …

    {
      Q1: 'Test 1',
      Q2: 'Test 2',
    }
    

    The final result then just needs to be mapped from the submittedValue‘s entries array, where each entry-key relates to the result’s state/test-name value and each entry-value is an object with just a single own property. The property name does not matter for the result-item’s answer-value will always be the first item of the object’s values array.

    Thus an efficient solution can be based on a single reduce task for creating the lookup and another single map task which already creates the final result …

    const data = [{
      id: 'Q1',
      state: 'Test 1',
      answers: [
        { id: 'Q1A1', text: 'Yes' },
        { id: 'Q1A2', text: 'No' },
      ],
    }, {
      id: 'Q2',
      state: 'Test 2',
      answers: [
        { id: 'Q2A1', text: 'Yes' },
        { id: 'Q2A2', text: 'No' },
      ],
    }];
    const submittedValue = {
      Q1: { Q1A1: 'Yes' },
      Q2: { Q2A2: 'No' },
    };
    
    // ... approach / solution ...
    
    const testNameLookup = data
      .reduce((lookup, testItem) => {
    
        const { id, state } = testItem;
        lookup[id] = state;
    
        return lookup;
      }, {});
    
    const result = Object
      .entries(submittedValue)
      .map(([ key, value ]) => {
    
        const state = testNameLookup[key];
        const answer = Object.values(value)[0];
    
        return { state, answer };
      });
    
    console.log({ result, testNameLookup });
    .as-console-wrapper { min-height: 100%!important; top: 0; }
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search