0

I have an array of objects called data and also have a separate object that is called mapping.

I try to delete the invalid object from the array. I have iterated the array using the map function. I check whether the object is valid using the mapping object. If it is found to be invalid then it should be deleted from the array, but the map function is not working asynchronously so they skip the invalid object, which is pushed into the array which is not fine. so please suggest some solution and also give me the small detail why map function is skipping the object.

Here my code:

 const data = [
        {
          id: 11,
          name: "dashboard",
        },

        {
          id: 13,
          name: "card",
        },

        {
          id: 1,
          name: "user",
        },

        {
          id: 4,
          name: "test",
        },
      ];

      const mapping = {
        1: "dashboard",
        2: "user",
        3: "card",
        4: "test",
      };

      const filterData = () => {
        data.map((parent, i) => {
          if (Object.keys(mapping).includes(parent.id.toString())) {
          } else {
            const index = data.indexOf(parent);
            if (index > -1) {
              data.splice(index, 1);
            }
          }
        });
        console.log("updated data", data);
      };

    ```
wrong output
[
 { id: 13, name: "card" },
    { id: 1, name: "user" },
   { id: 4, name: "test" }
    ];


Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
vjtechno
  • 452
  • 1
  • 6
  • 16

2 Answers2

1

You can use filter to delete invalid (based on some condition) objects from the array without modifying the original array.

const filterData = (data, mapping) => data.filter(item => mapping[item.id])
// Or
const filterData = (data, mapping) => data.filter(item => mapping[item.id] !== undefined)
// Or
const filterData = (data, mapping) => data.filter(item => mapping[item.id] !== void 0)

Demo:

const filterData = (data, mapping) => data.filter(item => mapping[item.id])

const data = [{
    id: 11,
    name: "dashboard",
  },
  {
    id: 13,
    name: "card",
  },
  {
    id: 1,
    name: "user",
  },
  {
    id: 4,
    name: "test",
  },
];

const mapping = {
  1: "dashboard",
  2: "user",
  3: "card",
  4: "test",
};

console.log(filterData(data, mapping))

Note that splice method will modify your original array i.e. data which you may not want.

Ajeet Shah
  • 18,551
  • 8
  • 57
  • 87
  • 1
    The solution is correct, I recommended your answer to be accepted in my answer, but nevertheless I needed to write another answer to show the asker the difference between his code and a working example. – Lajos Arpad Mar 08 '21 at 10:38
1

Ajeet Shah's solution is correct and I would apply the same idea, however, I think that a solution based on your code is also important so you will know what was the difference between your code and a correct one. However, I recommend accepting Ajeet's answer.

Let's see the following code:

 const data = [
        {
          id: 11,
          name: "dashboard",
        },

        {
          id: 13,
          name: "card",
        },

        {
          id: 1,
          name: "user",
        },

        {
          id: 4,
          name: "test",
        },
      ];

      const mapping = {
        1: "dashboard",
        2: "user",
        3: "card",
        4: "test",
      };

      const filterData = [];
      data.map((parent, i) => {
        if (Object.keys(mapping).includes(parent.id.toString())) {
          filterData.push(parent.id.toString());
        }
      });
      console.log(filterData);

The fix was to create an empty array and since map() is looping data, you just add the valid elements to the array you intend to use as an output. Even though this solution is correct, .map() is really meant to reinterpret the values and you logically need .filter(). As shown above, you can successfully filter by mapping, but writing code like above is less readable than writing the code in such a way that it clearly indicates that a filter is what happens.

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175