Home > Mobile >  Comparing two array of objects and getting the difference
Comparing two array of objects and getting the difference

Time:10-19

Hi I'm trying to show a loader for each input field, but only when they have entered a value. The behaviour i'm getting is if i enter a value into one of the text inputs the spinner shows for all. I need to determine my loading state based on the difference of the two arrays, by the array key.

Similar to this post -> How to get the difference between two arrays of objects in JavaScript

const [isLoading, setIsLoading] = useState('');

// before any value has been entered
const initialFormData = [{key: 'USER_DEFINED_QUESTIONS', value: ''}, {key: 'RECOMMENDED_FIELDS', value: ''}] 

// when a value has been entered
const values = [{key: 'USER_DEFINED_QUESTIONS', value: 'test'}, {key: 'RECOMMENDED_FIELDS', value: ''}] 


  const saveSubmit = async (values) => {
      const arrValues = Object.entries(values).map((val) => ({
        field: val[0],
        value: val[1],
      }));

      const arrInitialFormValues = Object.entries(initialFormData).map(
        (val) => ({
          field: val[0],
          value: val[1],
        }),
      );

      const result = arrValues.filter(
        (o1) => !arrInitialFormValues.some((o2) => o1.key === o2.key),
      );    

      const body = { ...values };
      setIsLoading(result);
      const res = await putResults({ id, body });
      if (res && !(await checkErrors(res))) {
        return res;
      }
      setIsLoading(result);
    }
    return null;
  };

CodePudding user response:

First of all, I would map the array into an object (this is not needed, it just feels cleaner this way).

    values = Object.fromEntries(a.map(entry => [entry.key, entry.value]))

Then I believe, all you really need is to find all entries that have non-negative "value" (if that is not the case, please comment below and I will correct this answer).

    usedFields = Object.entries(values).filter(entry => entry[1])

CodePudding user response:

You can combine the renaming and filter

const saveSubmit = async (values) => {
    const result = initialFormData.reduce((acc, a) => {
        const diff = values.find((b) => a.key === b.key && a.value !== b.value)
        return diff
            ? [
                  ...acc,
                  {
                      field: diff.key,
                      value: diff.value,
                  },
              ]
            : acc
    }, [])

    const body = { ...values }
    setIsLoading(result)
    const res = await putResults({ id, body })
    if (res && !(await checkErrors(res))) {
        return res
    }
    setIsLoading(result)
}

CodePudding user response:

If you want only to get the difference, and that is what i can read from question title, shouldn't this work?

const initialFormData = [{key: 'USER_DEFINED_QUESTIONS', value: ''}, {key: 'RECOMMENDED_FIELDS', value: ''}];
// when a value has been entered
const values = [{key: 'USER_DEFINED_QUESTIONS', value: 'test'}, {key: 'RECOMMENDED_FIELDS', value: ''}];
const result = values.filter(x => initialFormData.find(y=> x.key===y.key && x.value!==y.value));
   
console.log('res', result)
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related