MazMat
MazMat

Reputation: 2094

Mapping through array with undefined fields

I am implementing a hash table, where obviously some fields are left undefined, because they have not yet been filled.

I also want to display every field of the hash table. However, when I map through the array the function only returns divs for fields that are not undefined, cant figure out how to force map function to display Empty for undefined fields.

It looks like that for now:

const displayTable = () => {
  return storage.map(item => {
    if (item == null) {
      return <div>undefined</div>
    }
    return (
      <div>
        <p>{item[0][0]}</p>
      </div>
    );
  });

With storage being [undefined, undefined, undefined, Array[1], undefined, Array[1], undefined, undefined, undefined, Array[1]]

Thus I end up with only three rendered divs.

Upvotes: 0

Views: 449

Answers (4)

Bhojendra Rauniyar
Bhojendra Rauniyar

Reputation: 85545

For your actual solution I'd do just like below:

const displayTable = () => {
  return storage.map(item => {
    return (
      <div>
        {typeof item !== 'undefined' ? `<p>${item[0][0]}</p>` : 'Undefined'}
        Or just item to check, if it is defined
        {item ? `<p>${item[0][0]}</p>` : 'Undefined'} 
      </div>
    );
  });

A little bit different, though this might be helpful for others :)

const filteredStorage = storage.filter(item => item !== undefined);
const blankStorage = storage.filter(item => item === undefined);
const displayTable = () => {
  return (
   <div>
    <div>Undefined only</div>
    {
      blankStorage.map(item => {
        return <div>undefined</div>
      })
    }
    <div>Defined only</div>
    {
      filteredStorage.map(item => {
        return <div><p>{item[0][0]}</p></div>
      })
    }
  </div>
 )
}

Upvotes: 0

HMR
HMR

Reputation: 39270

You can use Array.from or spread operator if you have sparse arrays:

[1,2].concat(new Array(1)).forEach(x=>console.log("Only for 1 and 2:",x));
[1,2].concat([...new Array(1)]).forEach(x=>console.log("1, 2 and undefined:",x));//with spread operator
[1,2].concat(Array.from(new Array(1))).forEach(x=>console.log("1, 2 and undefined:",x));//with Array.from

Upvotes: 1

Lennholm
Lennholm

Reputation: 7470

In Javascript, undefined and not defined are not the same things, although trying to access a non-defined property of an object will return the value undefined. Considering JS also has null, this is in my opinion one of the messiest things about JS.

You could solve your issue by filling your array before starting to populate it:

storage.fill(null)

(Note that storage.fill(undefined) would also work! Isn't Javascript wonderful? :p)

Of course, this will only work if the array has a static, known length. If the length is dynamic, you'll have to do something like this:

const displayTable = () => {
  const rendered = [];
  for (let i = 0; i < storage.length; i++) {
    if (storage[i] == null) {
      rendered.push(<div>undefined</div>);
    } else {
      rendered.push(
        <div>
          <p>{storage[i][0][0]}</p>
        </div>
      );
    }
  }
  return rendered;
}

Upvotes: 3

Anthony
Anthony

Reputation: 6482

If the array is actually populated with undefined, you could do:

const displayTable = () => {
  return storage.map(item => {
    if(!item) {
      return <div> undefined </div>
    }
    return (
      <div>
        <p>{item[0][0]}</p>
      </div>
    );
  });

A fiddle with a working demonstration

NB. The example uses ternary but is functionally the same as above

But based on an example provided by the OP, this is not the case and the elements they are expecting to be undefined are actually empty i.e. there is nothing to invoke the .map() predicate on.

Upvotes: 1

Related Questions