0
\$\begingroup\$

I have a feature in my application that should allow users to select items in a drop down menu and move them up and down. Once they select and click on the button I have to loop over the array of objects and pull only records that were selected in the drop down menu.

Here is an example of my code:

var selectedColumns = ['first','last','city'];

var data = [
   {
      first: "Mike",
      last: "Ross",
      dob: "05/26/1978",
      city: "Washington DC",
      state: "DC",
      zip: 22904
   },
   {
      first: "John",
      last: "Henderson",
      dob: "11/06/1988",
      city: "Iowa City",
      state: "IA",
      zip: 52401
   },
   {
      first: "Nina",
      last: "Barkley",
      dob: "01/16/1968",
      city: "New York",
      state: "NY",
      zip: 11308
   },
   {
      first: "Jessie",
      last: "Kuch",
      dob: "02/02/1956",
      city: "Des Moines",
      state: "IA",
      zip: 55432
   },
   {
      first: "Jenny",
      last: "Terry",
      dob: "012/28/1988",
      city: "Miami",
      state: "FL",
      zip: 83943
   }
];

In the selected column we only have first, last and city. Then I have to loop over data and pull only selected columns. One way to do that is like this:

for(var key in data){
   for(var i=0; i<selectedColumns.length; i++){
      var columnID = String(columns[i]);
      console.log($.trim(data[key][columnID]));
   }
}

While this solution works just fine, I'm wondering if there is better way to avoid the inner loop and improve efficiency? I use jQuery/JavaScript in my project. If anyone knows a better way to approach this problem please let me know.

\$\endgroup\$
  • \$\begingroup\$ Welcome to Code Review? how is data[key][columnID] used (other than being logged to the console in the example)? \$\endgroup\$ – Sᴀᴍ Onᴇᴌᴀ Nov 9 '18 at 20:00
2
\$\begingroup\$

First of all, don't use for-in on arrays. for-in will loop over all enumerable properties, including non-index properties. Also, for-in order is not guaranteed. If you need a loop to go over array items only and in order, use for/while. Alternatively you can use array.forEach.

There's no way (that I know of) to remove that second loop, since you need to go over each selected property for each person in data. What you could do though is use native array methods. This way, you avoid the extra boilerplate that comes with loops like not going over the actual number of items.

What you really want is array.map. It's primary purpose is to create a new array based on another array, essentially a 1:1 transformation. In your case, you need to create an array that contains the same items but only selected properties.

For the inner loop, I suggest array.reduce. One use case for reduce is to condense an array of values into a single value. In this case, the selected keys into an object only containing the selected keys and their values.

var selectedColumns = ['first', 'last', 'city'];

var data = [{
    first: "Mike",
    last: "Ross",
    dob: "05/26/1978",
    city: "Washington DC",
    state: "DC",
    zip: 22904
  },
  {
    first: "John",
    last: "Henderson",
    dob: "11/06/1988",
    city: "Iowa City",
    state: "IA",
    zip: 52401
  },
  {
    first: "Nina",
    last: "Barkley",
    dob: "01/16/1968",
    city: "New York",
    state: "NY",
    zip: 11308
  },
  {
    first: "Jessie",
    last: "Kuch",
    dob: "02/02/1956",
    city: "Des Moines",
    state: "IA",
    zip: 55432
  },
  {
    first: "Jenny",
    last: "Terry",
    dob: "012/28/1988",
    city: "Miami",
    state: "FL",
    zip: 83943
  }
];

const onlySelected = data.map(person => {
  return selectedColumns.reduce((c, key) => {
    return { ...c, [key]: person[key] }
  }, {})
})

console.log(onlySelected)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.