Leo Messi
Leo Messi

Reputation: 6186

Get only the objects whom particular property is fulfilled in JavaScript

Having this array of objects:

myArray = [
    {name: "aaa", type: "1"},
    {name: "bbb", type: "2"},
    {name: "aaa", type: "3"},
    {name: "ddd", type: "1"},
    {name: "xxx", type: "3"},
    {name: "bbbb", type: "1"},
];

All this data is shown in a table. I'm implementing a drop-down selector which contains the list of type.

I want to be able to show in the table only the objects respecting the condition.

For example, if there is selected 1 from the selector it should show in the table this data:

{name: "aaa", type: "1"},
{name: "ddd", type: "1"},
{name: "bbbb", type: "1"},

For now, I have written function but it's not working.

updateTable(type) {
    const newArray = [];
    if (type === 1) {
        for (let i =0; i< myArray.length; i++) {
            if (myArray[i].type === 1) {
                newArray.push({myArray[i]});
            }
        }
    }
    if (type === 2) {
        for (let i =0; i< myArray.length; i++) {
            if (myArray[i].type === 2) {
                newArray.push({myArray[i]});
            }
        }
    }
    if (type === 3) {
        for (let i =0; i< myArray.length; i++) {
            if (myArray[i].type === 3) {
                newArray.push({myArray[i]});
            }
        }
    }
    return newArray;

}

I tried to do it by creating a new array which isn't the best way. Is there a solution without creating a new array?

Upvotes: 0

Views: 55

Answers (6)

Nina Scholz
Nina Scholz

Reputation: 386654

You could collapse not wanted rows by checking the option of the select element.

var array = [{ name: "aaa", type: "1" }, { name: "bbb", type: "2" }, { name: "aaa", type: "3" }, { name: "ddd", type: "1" }, { name: "xxx", type: "3" }, { name: "bbbb", type: "1" }],
    types = new Set;

array.forEach((o, i) => {
    var tr = document.createElement('tr');
    tr.id = 'row' + i;
    ['name', 'type'].forEach(k => {
        var td = document.createElement('td');
        td.innerHTML = o[k];
        tr.appendChild(td);
    });
    document.getElementById('tableData').appendChild(tr);
    types.add(o.type);
});

Array.from(types).sort((a, b) => a - b).forEach(t => {
    var option = document.createElement('option');
    option.value = t;
    option.innerHTML = t;
    document.getElementById('selectType').appendChild(option);
});

function update(element) {
    var option = element.options[element.selectedIndex].value;
    array.forEach((o, i) => {
        document.getElementById('row' + i).style.visibility = !option || option === o.type
            ? 'visible'
            : 'collapse';
    });
}
<select id="selectType" onchange="update(this)">
    <option value="">all</option>
</select>
<table id="tableData">
    <tr>
        <th>name</th>
        <th>type</th>
    </tr>
</table>

Upvotes: 0

Narendra Jadhav
Narendra Jadhav

Reputation: 10262

ES6

Is there a solution without creating a new array

Yes for this, you could use filter() this return filtered data based on condition passed.

DEMO

const myArray = [
    {name: "aaa", type: "1"},
    {name: "bbb", type: "2"},
    {name: "aaa", type: "3"},
    {name: "ddd", type: "1"},
    {name: "xxx", type: "3"},
    {name: "bbbb", type: "1"}
];

function updateTable(value) {
 return myArray.filter(({type})=>type==value);
}


console.log(updateTable("1"));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 0

Joe Warner
Joe Warner

Reputation: 3452

You can use reduce

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

this will reduce an object with keys of all your types with an array containing those types

const myArray = [
  {
    name: "aaa",
    type: "1"
  },
  {
    name: "bbb",
    type: "2"
  },
  {
    name: "aaa",
    type: "3"
  },
  {
    name: "ddd",
    type: "1"
  },
  {
    name: "xxx",
    type: "3"
  },
  {
    name: "bbbb",
    type: "1"
  },
];

function filterIntoTypes() {
  return myArray.reduce((p, c) => {
    if (!p[c.type]) {
      p[c.type] = []
    }
    p[c.type] = [...p[c.type], c]
    return p;
  }, {})
}

const types = filterIntoTypes()


console.log(types['1'])
console.log(types['2'])
console.log(types['3'])

Upvotes: 0

Keith
Keith

Reputation: 24191

Is there a solution without creating a new array?

Yes, but often creating a new array is usually better,. Objects inside arrays are only references so it's not like it a memory / performance issue. btw. Array.map, Array.filter create new arrays.

But if you still want to update the original array, you can use splice to delete the ones you don't want. Trick here though is to go through the array backwards as the length changes as going forward could skip required indexes.

var myArray = [
    {name: "aaa", type: "1"},
    {name: "bbb", type: "2"},
    {name: "aaa", type: "3"},
    {name: "ddd", type: "1"},
    {name: "xxx", type: "3"},
    {name: "bbbb", type: "1"}
];

function updateTable(type) {
  for (var l = myArray.length - 1; l >= 0; l --) {
    if (myArray[l].type !== type) {
      myArray.splice(l, 1);
    }
  }
}

updateTable("1");
console.log(myArray);

Upvotes: 0

Parthipan Natkunam
Parthipan Natkunam

Reputation: 784

The filter method can be used for this purpose:

updateTable(type) {
    return myArray.filter(elem => elem.type == type);
}

Upvotes: 0

Nikhil Aggarwal
Nikhil Aggarwal

Reputation: 28455

Firstly, your code was not working because of type === 1. Because (===) check value and type. And in array type is a string but in the function argument it is a number. Hence, it is never equated to true.

Secondly, update your function to following

updateTable(type) {
   return myArray.filter(function(item){
      return item.type == type;
   });
}

Upvotes: 1

Related Questions