Home > Blockchain >  Finding a value in nested array then returning a value from the upper scope
Finding a value in nested array then returning a value from the upper scope

Time:10-28

What I am trying to achieve is:

  1. Find if the text object within array is empty.
  2. If criteria from no1 is matched, then return id value that sits in the top level of that object.

https://codesandbox.io/s/cranky-swirles-gb6ct?file=/src/App.js:410-412 In the code sandbox's example I have added two objects, with empty text strings and in that case I would expect to get an array of strings back (result = ['662e4120', '782h7a9x'])

I am able to find empty values, however I am not sure how to return object from the upper scope.

If you can't access the codeSandbox, snippet is attached just below:

const array = [
{
  id: "5548d3c2",
  state: {
    properties: [
      {
        text: "text",
        key: "fs5a"
      }
    ]
  }
},
{
  id: "662e4120",
  state: {
    properties: [
      {
        text: "",
        key: "m03n"
      }
    ]
  }
},
{
  id: "782h7a9x",
  state: {
    properties: [
      {
        text: "",
        key: "y5x1"
      }
    ]
  }
}];

  const findItem = () => {
    return array
      .map((item) => item.state)
      .map((item) => item.properties)
      .flat()
      .filter((item) => item.text === "");
  };

CodePudding user response:

Try to do something like this https://codesandbox.io/s/jovial-mcnulty-2fwh4

export default function App() {
  const array = [
    {
      id: "5548d3c2",
      state: {
        properties: [
          {
            text: "text",
            key: "fs5a"
          }
        ]
      }
    },
    {
      id: "662e4120",
      state: {
        properties: [
          {
            text: "",
            key: "m03n"
          }
        ]
      }
    },
    {
      id: "782h7a9x",
      state: {
        properties: [
          {
            text: "",
            key: "y5x1"
          }
        ]
      }
    }
  ];

  const findItem = () => {
    return array.filter(obj=>obj.state.properties[0].text==="").map(obj=>obj.id)
  };

  console.log(findItem());

  return <div className="App"></div>;
}

Here, we are filtering on the original array based on a predicate which is obj=>obj.state.properties[0].text==="". This basically get all the elements of the array which satisfy this predicate function. After this we are just applying map over the result to get the ids of the array elements satisfying this predicate function.

CodePudding user response:

To get an array with the ids of the objects with no text you have to change the order or your iterations.

  1. .filter() the array for the elements with empty text fields.
  2. .map() the remaining elements to the values you are aiming for

When mapping or filtering you can't go just one but as many levels deep as you like. Since 'properties' holds an array and you want the first element you access that with the index array[0] (with that the flat() you did is superfluous)

  const findItem = () => {
    return array
      .filter(item => item.state.properties[0].text === "")   // (2) [{…}, {…}] the original items with no text
      .map(item => item.id)  // ['662e4120', '782h7a9x']
  };

(code might be as well embedded as a snippet, which can be run directly)

const array = [
{
  id: "5548d3c2",
  state: {
    properties: [
      {
        text: "text",
        key: "fs5a"
      }
    ]
  }
},
{
  id: "662e4120",
  state: {
    properties: [
      {
        text: "",
        key: "m03n"
      }
    ]
  }
},
{
  id: "782h7a9x",
  state: {
    properties: [
      {
        text: "",
        key: "y5x1"
      }
    ]
  }
}];

  const findItem = () => {
    return array
      .filter(item => item.state.properties[0].text === "")   // (2) [{…}, {…}] the original items with no text
      .map(item => item.id)  // ['662e4120', '782h7a9x']
  };

console.log(findItem())
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related