根据键映射 2 个数组

Map 2 arrays based on key

我有一个包含一些日期和值的数组。例如:在日期 x 我们有 20 个订单,在日期 y 我们有 32 个订单。

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

第二个数组是一个包含上个月所有日期的数组。例如:

["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"]

然后我尝试映射这个数组并检查日期是否为空,写入“”,否则写入在第一个数组中找到的值。

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

它将给我一个长度为 31 的数组,其中数组元素有 2 个值。日期 => 值。如果在第一个数组中找不到日期,它会写入“”,但他无法在第一个数组中找到该值。这件事我哪里错了?

首先,根据 问题

,使这项工作如您所料

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...

我建议采用以下方法:

// 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.

现在,您的代码未按预期工作的原因:

  1. [2016-08-09: 38, 2016-08-08: 75, 2016-08-05: 13, 2016-08-04: 23, 2016-08-03: 10] 这是一个语法错误,数组值——这是一个数组,而不是一个对象——需要被引用,否则我们会得到一个错误"Uncaught SyntaxError: Unexpected token :" 3.

  2. 当您尝试使用 none-数字数组元素作为访问另一个数组中保存的值的键时,这将 return 一个未定义的值,因为可以使用相同的表示法访问您尝试访问的数组,但使用数字索引,例如 inputOrdersCount[0] (这将导致 "2016-08-09: 38" (如果您引用了数组元素)。而你 想要 检索的是 38,这要求 inputOrdersCount 是一个对象,因此我在上面的演示中将数组更改为对象。

  3. 你的条件(三元)运算符是错误的;你应该做的是 - 如果你的 inputOrdersCount[date] 检查结果是肯定的 - 那么你 return 这个结果,如果检查没有结果你 return 空字符串。不幸的是,鉴于您的语句顺序,您所做的恰恰相反: return 当检查为正并提供未定义结果时为空字符串(如果没有正数,则为相同的 inputOrdersCount[date] 结果,真或真实的结果。三元组的顺序很重要并遵循以下模式:

    assessment ? ifTrue : ifFalse;
    

    所以你应该写成:

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

参考文献:


脚注:

  1. 重现语法错误,在变量名中使用连字符:https://jsfiddle.net/davidThomas/842q0s89/1/
  2. 重现语法错误,使用括号尝试将求和结果用作对象键:https://jsfiddle.net/davidThomas/842q0s89/2/
  3. 重现错误,"Uncaught SyntaxError: Unexpected token :"

如果您需要将字符串数组转换为对象才能执行 inputOrdersCount[date],您可以像这样使用 reduce

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);