sunzhida
sunzhida

Reputation: 35

Comparing an Array with an Objects' Array in JavaScript

I am new to JavaScript and wondering how can I compare an array with another array consists of JavaScript objects.

  1. The array is a series of sorted time in the "YYYY-MM-DD" format.
  2. The array of objects missed some price values of several days.
  3. I want to find the missed value and assign it as "NULL".

For example, I have an array as:

array = ['2014-10-09','2014-10-10','2014-10-11','2014-10-12'];

and an array with objects as:

objArray = [{
    date:"2014-10-09",
    price:"100"
},
{
    date:"2014-10-10",
    price:"99"
},
{
    date:"2014-10-12",
    price:"102"
}];

I want to get the price array in this way:

priceResult = [100, 99, "NULL", 102];

What would be the most efficient way without using other libraries? I wanted to see if anyone had a more elegant solution. I deeply appreciate your help.

Upvotes: 0

Views: 152

Answers (9)

deitch
deitch

Reputation: 14581

lodash is the best library for this. But you did say "without using other libraries", so you will need to do it natively.

The easiest way to do it is nested for loops:

var i, j, d, res = [];
for (i=0; i<dateArray.length; i++) {
  d = dateArray[i];
  for (j=0; j<objArray.length; j++) {
    if (objArray[j] && objArray[j].date && objArray[j].date === d) {
       res.push(objArray[j].price);
       j = objArray.length; // don't waste energy searching any more, since we found it
    }
  }
}
// res now contains all you wanted

If objArray is really big, and you don't want to search it multiple times, then you could turn it into an object indexed by date:

var i, obj = {}, d, res = [];
for (i=0; i<objArray.length; i++) {
  if (objArray[i] && objArray[i].date) {
    obj[objArray[i].date] = objArray[i];
  }
}
for (i=0; i<dateArray.length; i++) {
  d = dateArray[i];
  res.push(obj[d] ? obj[d].price : null : null);
}
// res now contains all you wanted

Upvotes: 0

Guffa
Guffa

Reputation: 700232

You can create a lookup set from the object array, then you can use that to translate the dates to prices.

This scales well, as it is an O(n+m) solution rather than the O(n*m) solution that you get if you use a loop in a loop to find the prices.

var array = ['2014-10-09','2014-10-10','2014-10-11','2014-10-12'];
var objArray = [{ date:"2014-10-09", model:"A", price:"100" },{ date:"2014-10-10", model:"A", price:"99" },{ date:"2014-10-12", model:"A", price:"102" }];

var lookup = {};
for (var i = 0; i < objArray.length; i++) {
  lookup[objArray[i].date] = parseInt(objArray[i].price, 10);
}

var priceResult = [];
for (var i = 0; i < array.length; i++) {
  if (lookup.hasOwnProperty(array[i])) {
    priceResult.push(lookup[array[i]]);
  } else {
    priceResult.push('NULL');
  }
}

// output result in StackOverflow snippet
document.write(JSON.stringify(priceResult));

Note: Instead of the string 'NULL' you might want to use the value null instead, as it is generally easier to handle.

Upvotes: 1

saikumarm
saikumarm

Reputation: 1575

dateArray = ["2014-10-09", "2014-10-10", "2014-10-11", "2014-10-12"];
function ObjectExample(date1,model,price)
{
    this.date1 = date1;
    this.model = model;
    this.price = price;
}
var objArray = [new ObjectExample("2014-10-09","A","100"), new ObjectExample("2014-10-10","A","99"), new ObjectExample("2014-10-12","A","102")];
var i = 0;
var priceDate = new Array();
var count = 0;
while(i < dateArray.length)
{
    var j = 0;
    while(j < objArray.length)
    {
        if(dateArray[i] == objArray[j].date1)
        {
             priceDate[count] = objArray[j].price;
             break;
        }
        else priceDate[count] = "NULL";
        j = j + 1;
    }
    i = i + 1;
    count++;
}
document.write(priceDate);

Upvotes: 0

Dhaval
Dhaval

Reputation: 2379

Try this:

var temp[] 

temp= jQuery.grep(objArray , function (n, i)

 { 
    for(j=0;j<dateArray.lenght+j++ )
        if( n.date === dateArray[j])
            return n.price;
 );

Upvotes: 0

Ghassan Elias
Ghassan Elias

Reputation: 2233

var dates = ['2014-10-09','2014-10-10','2014-10-11','2014-10-12'];
var objArray = [{date:"2014-10-09", model:"A", price:"100" }, {date:"2014-10-10", model:"A", price:"99" }, {date:"2014-10-12", model:"A", price:"102" }];

var val;
var priceResult = [];
for (var a in dates) {
    val = null;
    for (var b in objArray) {
        if (dates[a] == objArray[b].date) {
            val = objArray[b].price;
        }
    }
    priceResult.push(val);
}

    var dates = ['2014-10-09', '2014-10-10', '2014-10-11', '2014-10-12'];
    var objArray = [{
      date: "2014-10-09",
      model: "A",
      price: "100"
    }, {
      date: "2014-10-10",
      model: "A",
      price: "99"
    }, {
      date: "2014-10-12",
      model: "A",
      price: "102"
    }];

    var val;
    var priceResult = [];
    for (var a in dates) {
      val = null;
      for (var b in objArray) {
        if (dates[a] == objArray[b].date) {
          val = objArray[b].price;
        }
      }
      priceResult.push(val);
    }

     // output result in StackOverflow snippet
    document.write(JSON.stringify(priceResult));

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1074148

(I'm going to call your first array dates rather than array, to avoid confusion.)

There are basically two options:

  1. Loop through your dates array and, for each entry, loop through the objArray looking for a match, and when found add to your priceResult array, or

  2. Build a map from your objArray, then loop through yourdatesarray once, building thepriceResult` array.

Looping and Looping

You can loop through your dates array using forEach, and you can use Array#some to find out whether your objArray contains the date and add to priceResult if so (it's an ES5 feature, but you can polyfill it for really old browsers):

var priceResult = [];
dates.forEach(function(date) {
    objArray.some(function(object) {
        if (object.date == date) {
            priceResult.push(object.price);
            return true;
        }
    });
});

Array#some keeps looping until you return true, which is why we do that when we find the firs tmatch. That's why I say this is "looping and looping," even though we only write one loop, the other is within Array#some.

var dates = ['2014-10-09', '2014-10-10', '2014-10-11', '2014-10-12'];

var objArray = [
  {
    date: "2014-10-09",
    model: "A",
    price: "100"
  },
  {
    date: "2014-10-10",
    model: "A",
    price: "99"
  },
  {
    date: "2014-10-12",
    model: "A",
    price: "102"
  }
];

// Do it
var priceResult = [];
dates.forEach(function(date) {
  objArray.some(function(object) {
    if (object.date == date) {
      priceResult.push(object.price);
      return true;
    }
  });
});
snippet.log(priceResult.join(", "));
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Mapping and Looping

First, create a map of prices by date:

var prices = {};
objArray.forEach(function(object) {
    prices[object.date] = object.price;
});

...then create your results:

var priceResult = [];
dates.forEach(function(date) {
    if (prices.hasOwnProperty(date)) {
        priceResult.push(prices[date]);
    }
});

var dates = ['2014-10-09', '2014-10-10', '2014-10-11', '2014-10-12'];

var objArray = [
  {
    date: "2014-10-09",
    model: "A",
    price: "100"
  },
  {
    date: "2014-10-10",
    model: "A",
    price: "99"
  },
  {
    date: "2014-10-12",
    model: "A",
    price: "102"
  }
];

// Create the map
var prices = {};
objArray.forEach(function(object) {
  prices[object.date] = object.price;
});

// Create your results:
var priceResult = [];
dates.forEach(function(date) {
  if (prices.hasOwnProperty(date)) {
    priceResult.push(prices[date]);
  }
});

// Show them
snippet.log(priceResult.join(", "));
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Upvotes: 0

KaustubhSV
KaustubhSV

Reputation: 358

If i am understanding your question correctly, for all the values in array, you want to check the objArr and find the price for each date, and if not found u want to inset null. If this is what you want, then following will help

       var found= false; 
       var list=[];  
    for(var i=0; i< dateArray.length; i++)
    {
        for(var j=0; j< objArray.length; j++)
        {
            if(objArray[j].date ==  dateArray[i])
            {
            list.push(objArray[j].price);
            found =  true;
            }
        }
        if(!found)
        {
        list.push("null");
        }
        found = false;
    }

alert(list);

Upvotes: 0

Moazzam Khan
Moazzam Khan

Reputation: 3170

This function will give you map of all individual arrays in your object array

function getArrayMap(array) {
    var map={}
    for(var i=0;i<array.length;i++){
        var o = array[i];
        for(var k in o){
            if(!map[k]){
                map[k]=[];
            }
            map[k].push(o[k]);
        }
    }
    return map;
}

you can use it like -

var map = getArrayMap(objArray);

console.log(map["date"]);//date array
console.log(map["price"]);//price array
console.log(map["model"]);//model array

Upvotes: 0

Mettin Parzinski
Mettin Parzinski

Reputation: 898

Loop trough the object and search for the date in your array

// Add contains to array proto: http://css-tricks.com/snippets/javascript/javascript-array-contains/
var priceResult = [];
for(var i in objArray) {
    if(dateArray.contains(objArray[i].date)) priceResult.push(objArray[i].date));
}
console.log('matches:', priceResult);

Upvotes: 0

Related Questions