Mihai Gota
Mihai Gota

Reputation: 97

Map 2 arrays based on key

I have an array with some dates and values. Eg: In date x we have 20 orders, in date y we have 32 orders.

[2016-08-09: 38, 2016-08-08: 75, 2016-08-05: 13, 2016-08-04: 23, 2016-08-03: 10]

The second array is an array with all dates from last month. Eg:

["2016-07-14", "2016-07-15", "2016-07-16", "2016-07-17", "2016-07-18", "2016-07-19", "2016-07-20", "2016-07-21", "2016-07-22", "2016-07-23", "2016-07-24", "2016-07-25", "2016-07-26", "2016-07-27", "2016-07-28", "2016-07-29", "2016-07-30", "2016-07-31", "2016-08-01", "2016-08-02", "2016-08-03", "2016-08-04", "2016-08-05", "2016-08-06", "2016-08-07", "2016-08-08", "2016-08-09", "2016-08-10", "2016-08-11", "2016-08-12", "2016-08-13"]

Then I tried to map this arrays and check the date if is empty, write "" else write the value found in the first array.

        var totalInputOrders = allDates.map(function(date) {
          return [ date, inputOrdersCount[date] ? "" : inputOrdersCount[date] ];
      });

It will give me an 31 length array with array elements with 2 values. Date => Value. If date is not found in the first array it writes "" but he cannot find the value in the first array. Where am I wrong in this matter?

Upvotes: 0

Views: 107

Answers (2)

Aprillion
Aprillion

Reputation: 22340

In case you need to convert the array of strings into an object to be able to do the inputOrdersCount[date], you can use reduce like this:

var inputOrdersCount = ["2016-08-09: 38", "2016-08-08: 75", "2016-08-05: 13", "2016-08-04: 23", "2016-08-03: 10"];

inputOrdersCount = inputOrdersCount.reduce(function(counter, item) {
  var split = item.split(/: ?/);
  counter[split[0]] = parseInt(split[1], 10);
  return counter;
}, {});

console.log(inputOrdersCount);

Upvotes: 0

David Thomas
David Thomas

Reputation: 253486

First, to make this work as you seem to expect, based on your comment to the question:

I'm expecting: [[2016-08-10, ""], [2016-08-09, 38], [2016-08-08, 75], [2016-08-07, ""], [2016-08-06, ""], [2016-08-05, 13]] and so on...

I'd suggest the following approach:

// using an Object, in place of an Array, to associate
// dates with order-counts, and wrapping the dates in
// quotes (otherwise you have invalid syntax [1], hyphens
// cannot be used unquoted in variable names even if
// wrapped in parentheses to attempt to have the result
// of a mathematical expression be used as the key [2]):
var inputOrdersCount = {
    "2016-08-09": 38,
    "2016-08-08": 75,
    "2016-08-05": 13,
    "2016-08-04": 23,
    "2016-08-03": 10
  },

  // no changes to this Array:
  allDates = ["2016-07-14", "2016-07-15", "2016-07-16", "2016-07-17", "2016-07-18", "2016-07-19", "2016-07-20", "2016-07-21", "2016-07-22", "2016-07-23", "2016-07-24", "2016-07-25", "2016-07-26", "2016-07-27", "2016-07-28", "2016-07-29", "2016-07-30", "2016-07-31", "2016-08-01", "2016-08-02", "2016-08-03", "2016-08-04", "2016-08-05", "2016-08-06", "2016-08-07", "2016-08-08", "2016-08-09", "2016-08-10", "2016-08-11", "2016-08-12", "2016-08-13"],

  // using Array.prototype.map() to iterate over the allDates
  // Array:
  totalInputOrders = allDates.map(function(date) {
    // 'date', the first argment, is a reference to
    // the current array-element of the Array over
    // which we're iterating.

    // here we return an Array with the current
    // array-element as the first array-element
    // of the created-Array, and the second value
    // determined by the existence of a result
    // from the inputOrdersCount Object using
    // the current array-element as the key; if
    // there is a result we use that result, if
    // no result (undefined) then we use an
    // empty string:
    return [date, (inputOrdersCount[date] ? inputOrdersCount[date] : "")];
  });

// logging the full totalInputOrders Array, and the filtered
// totalInputOrders Array, returning only those Array-elements
// that do not have an empty String as the second array-element:
console.log(totalInputOrders, totalInputOrders.filter(function(arr) {
  return arr[1] !== "";
}));

JS Fiddle demo.

Now, the reasons your code didn't work as you expected:

  1. [2016-08-09: 38, 2016-08-08: 75, 2016-08-05: 13, 2016-08-04: 23, 2016-08-03: 10] this is a syntax error, the array-values – and this is an Array, not an Object – would need to be quoted, because otherwise we end up with an error of "Uncaught SyntaxError: Unexpected token :" 3.

  2. As you're trying to use a none-numeric array-element as the key to access the value held in another Array this will return an undefined value, because the Array you're trying to access can be accessed using the same notation, but using a numerical index, for example inputOrdersCount[0] (which would result in "2016-08-09: 38" (had you quoted your array-elements). Whereas what you want to retrieve is 38, which requires the inputOrdersCount to be an Object, hence my changing the Array to an Object in the above demo.

  3. Your conditional (ternary) operator is wrong; what you should be doing is – if you have a positive result from your inputOrdersCount[date] check – then you return that result, and if no result from the check you return the empty string. Unfortunately, given the order of your statements you're doing the exact opposite: return an empty string when the check is positive and supplying an undefined result (the same inputOrdersCount[date] result if there is no positive, true or truthy result. The order of the ternary is important and follows the pattern:

    assessment ? ifTrue : ifFalse;
    

    So you should have written instead:

    inputOrdersCount[date] ? inputOrdersCount[date] : "";
    

References:


Footnotes:

  1. Reproduction of syntax error, using hyphens in variable-names: https://jsfiddle.net/davidThomas/842q0s89/1/
  2. Reproduction of syntax error, using parentheses to attempt to use the result of a sum as an Object key: https://jsfiddle.net/davidThomas/842q0s89/2/
  3. Reproduction of error, "Uncaught SyntaxError: Unexpected token :"

Upvotes: 2

Related Questions