Urs Bo
Urs Bo

Reputation: 342

How to get data from multidimensional array in JavaScript?

I have the following array:

var data = [{
  length: 900,
  fields: 3
},{
  length: 1150,
  fields: 4
},{
  length: 1700,
  fields: 5
}];

Now I would like to have a function that returns the fields depending on the given length like:

function getFields(length) {
   // return "3" if length <= 900
   // return "4" if length <= 1150
   // return "5" if length <= 1700
}

How could I achieve this?

Upvotes: 0

Views: 183

Answers (4)

epascarello
epascarello

Reputation: 207557

As long as data is properly sorted, it is a simple for loop

var data = [{
  length: 900,
  fields: 3
},{
  length: 1150,
  fields: 4
},{
  length: 1700,
  fields: 5
}];

function getFields (value) {
  var i;
  for (i=0; i<data.length; i++) {
    if (value <= data[i].length) return data[i].fields;  // exit since we found first match
  }
  return 0; // what ever the default is for no match
}

console.log(800, getFields(800));
console.log(900, getFields(900)); 
console.log(1000, getFields(1000)); 
console.log(1500, getFields(1500)); 
console.log(2000, getFields(2000));

or with modern array methods you can use find() which is like a for loop code above under the hood:

var data = [{
  length: 900,
  fields: 3
},{
  length: 1150,
  fields: 4
},{
  length: 1700,
  fields: 5
}];

function getFields (value) {
  var i;
  var match = data.find(function(item) { 
    return value <= item.length
  })
  return match ? match.fields : 0;
}

console.log(800, getFields(800));
console.log(900, getFields(900)); 
console.log(1000, getFields(1000)); 
console.log(1500, getFields(1500)); 
console.log(2000, getFields(2000));

Now if the data array is out of order, than it should be sorted.

Upvotes: 2

pete
pete

Reputation: 25091

I'd define it like so:

function getFields(length) {
   var d = data
            .filter(d => d.length <= length)        // get the list of matching objects
            .sort((a, b) => b.length - a.length)    // sort descending so largest value is at the front of the array
            .shift();                               // get the first element from the array
    return (d !== undefined) ? d.fields : undefined;// if that element exists, return .fields, otherwise undefined
}

In action:

var data = [{
    length: 900,
    fields: 3
},{
    length: 1150,
    fields: 4
},{
    length: 1700,
    fields: 5
}];

function getFields(length) {
   var d = data
            .filter(d => d.length <= length)        // get the list of matching objects
            .sort((a, b) => b.length - a.length)    // sort descending so largest value is at the front of the array
            .shift();                               // get the first element from the array
    return (d !== undefined) ? d.fields : undefined;// if that element exists, return .fields, otherwise undefined
}

var tests = [1700, 1150, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700];
console.log(tests.map(getFields));

While I don't know if this is performant enough for your current use case, but it's relatively readable and easy-to-follow (although this could be made more efficient if the data were always ordered by length, for instance). If you need something more performant, you could do something like this instead:

function getFields(length) {
    let d;
    let i = data.length - 1;

    while (i > -1 && d === undefined) {
        if (data[i].length <= length) {
            d = data[i].fields;
        }
        i -= 1;
    }

    return d;
}

In action:

var data = [{
    length: 900,
    fields: 3
},{
    length: 1150,
    fields: 4
},{
    length: 1700,
    fields: 5
}];

function getFields(length) {
    let d;
    let i = data.length - 1;
    
    while (i > -1 && d === undefined) {
        if (data[i].length <= length) {
            d = data[i].fields;
        }
        i -= 1;
    }
    
    return d;
}

var tests = [1700, 1150, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700];
console.log(tests.map(getFields));

Upvotes: 1

Peter B
Peter B

Reputation: 24280

You don't need jQuery for this, it can be done with e.g. a standard .find() call. Note that this assumes that the data is sorted by .length as in your example.

var data = [{
  length: 900,
  fields: 3
}, {
  length: 1150,
  fields: 4
}, {
  length: 1700,
  fields: 5
}];

var value = 950;
var matching = data.find(x => value <= x.length);
var fields = matching ? matching.fields : 0;

console.log(fields);

Upvotes: 1

Bhushan Kawadkar
Bhushan Kawadkar

Reputation: 28523

you can iterate the data and match the conditon

var data = [{
  length: 900,
  fields: 3
},{
  length: 1150,
  fields: 4
},{
  length: 1700,
  fields: 5
}];

   function getFields(len) {
var fields = '';
$.each(data, function(key,value) {
  if(value.length<=len)
     fields = value.fields;
}); 
 return fields;
}

   // call function 
   alert(getFields(1700));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Upvotes: 1

Related Questions