spas2k
spas2k

Reputation: 519

jquery map with conditions

Is there a way to add a condition to a map function?

I'm trying to get the computer names of workstations that are win7 and ready, omitting the win10 machines.

Is there any good way to get the 2 workstations using the map command or should I look for a different approach?

$('#get').click(function() {
  var grids = $('.highlight').map(function() {
    return this.id;
  }).get().join();
  console.log(grids);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <th>Workstation</th>
  <th>Version</th>
  <th>Status</th>
  <tr>
    <td id="mac1" class='highlight'>mac1</td>
    <td>win7</td>
    <td class='status'>ready</td>
  </tr>
  <tr>
    <td>mac2</td>
    <td>win7</td>
    <td class='status'>not ready</td>
  </tr>
  <tr>
    <td id="mac3" class='highlight'>mac3</td>
    <td>win10</td>
    <td class='status'>ready</td>
  </tr>
  <tr>
    <td>mac4</td>
    <td>win10</td>
    <td class='status'>ready</td>
  </tr>
  <tr>
    <td>mac5</td>
    <td>win7</td>
    <td class='status'>not ready</td>
  </tr>
  <tr>
    <td id='mac6' class='highlight'>mac6</td>
    <td>win7</td>
    <td class='status'>ready</td>
  </tr>
</table>

<div class='button' id='get'>Get</div>

https://jsfiddle.net/mLf5az63/3/

Upvotes: 0

Views: 102

Answers (3)

Rohit Shetty
Rohit Shetty

Reputation: 504

You can do it this way:

$('#get').click(function () {
  var grids = $('.highlight').map(function () {
        var type = $(this).next('td')[0].innerText;
        var status = $(this).next('td').next('td')[0].innerText;
        if(type == 'win7' && status == 'ready') {
            return this.id;
        }
   }).get().join();
   console.log(grids);
});

I have updated your JS fiddle as well, you can test there.

https://jsfiddle.net/yov7ugjx/2/

Upvotes: 1

Taplar
Taplar

Reputation: 24965

One approach you could do is to put the children details on the tr as data elements. Then after finding the highlighted elements, you can find their parent rows, filter on the ones you want, and then perform your map.

$('#get').on('click', function() {
  var grids = $('.highlight')
    .closest('tr')
    .filter(function(){
      return this.dataset.os === 'win7' && this.dataset.status === 'ready'
    })
    .map(function() {
      return this.dataset.id;
    }).get().join();
    
  console.log(grids);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <th>Workstation</th>
  <th>Version</th>
  <th>Status</th>
  <tr data-id="mac1" data-os="win7" data-status="ready">
    <td id="mac1" class='highlight'>mac1</td>
    <td>win7</td>
    <td class='status'>ready</td>
  </tr>
  <tr data-id="mac2" data-os="win7" data-status="not ready">
    <td>mac2</td>
    <td>win7</td>
    <td class='status'>not ready</td>
  </tr>
  <tr data-id="mac3" data-os="win10" data-status="ready">
    <td id="mac3" class='highlight'>mac3</td>
    <td>win10</td>
    <td class='status'>ready</td>
  </tr>
  <tr data-id="mac4" data-os="win10" data-status="ready">
    <td>mac4</td>
    <td>win10</td>
    <td class='status'>ready</td>
  </tr>
  <tr data-id="mac5" data-os="win7" data-status="not ready">
    <td>mac5</td>
    <td>win7</td>
    <td class='status'>not ready</td>
  </tr>
  <tr data-id="mac6" data-os="win7" data-status="ready">
    <td id='mac6' class='highlight'>mac6</td>
    <td>win7</td>
    <td class='status'>ready</td>
  </tr>
</table>

<div class='button' id='get'>Get</div>

Upvotes: 1

lumio
lumio

Reputation: 7575

.map is probably a good solution, combined with .filter, if you don't have too many elements. This is even possible without using jQuery at all like so.

document.getElementById('get').addEventListener('click', () => {
  const grids = Array.from(document.querySelectorAll('tr'))
    .map(line => {
      // Get the first cell with the id or undefined if not available
      const id = (line.querySelector('td:nth-child(1)') || {}).id;
      // Get the second cells content
      const version = (line.querySelector('td:nth-child(2)') || {}).innerText;
      // And lastly the status
      const status = (line.querySelector('.status') || {}).innerText;

      // Check version and status and return the id
      if (version === 'win7' && status === 'ready') {
        return id;
      }

      // Otherwise something falsy
      return null;
    })
    // Only return item when it is tru'ish
    .filter(item => item);
  console.log(grids);
});
<table>
  <th>Workstation</th>
  <th>Version</th>
  <th>Status</th>
  <tr>
    <td id="mac1" class='highlight'>mac1</td>
    <td>win7</td>
    <td class='status'>ready</td>
  </tr>
  <tr>
    <td>mac2</td>
    <td>win7</td>
    <td class='status'>not ready</td>
  </tr>
  <tr>
    <td id="mac3" class='highlight'>mac3</td>
    <td>win10</td>
    <td class='status'>ready</td>
  </tr>
  <tr>
    <td>mac4</td>
    <td>win10</td>
    <td class='status'>ready</td>
  </tr>
  <tr>
    <td>mac5</td>
    <td>win7</td>
    <td class='status'>not ready</td>
  </tr>
  <tr>
    <td id='mac6' class='highlight'>mac6</td>
    <td>win7</td>
    <td class='status'>ready</td>
  </tr>
</table>

<button id='get'>Get</button>

Upvotes: 1

Related Questions