在javascript中查找匹配数组中的最大值和最小值

时间:2017-10-11 04:14:05

标签: javascript arrays

我有一个像下面的对象......

var SpecialObj=
{   
    "dataarray-345":
    [
        {lqd: 1000, date: "2017-08-18 09:30:00"},
        {lqd: 5000, date: "2017-08-18 10:00:00"},
        {lqd: 5500, date: "2017-08-18 10:30:00"},
        {lqd: 4500, date: "2017-08-18 11:00:00"},
        {lqd: 1500, date: "2017-08-18 11:30:00"}
    ],
    "dataarray-123":
    [

        {lqd: 5000, date: "2017-08-18 10:00:00"},
        {lqd: 5500, date: "2017-08-18 10:30:00"},
        {lqd: 4500, date: "2017-08-18 11:00:00"},
        {lqd: 1500, date: "2017-08-18 11:30:00"},
        {lqd: 2500, date: "2017-08-18 12:00:00"},
        {lqd: 3500, date: "2017-08-18 12:30:00"}
    ],
    "dataarray-127":
    [
        {lqd: 8500, date: "2017-08-18 13:00:00"},
        {lqd: 9500, date: "2017-08-18 13:30:00"},
        {lqd: 6500, date: "2017-08-18 14:00:00"}
    ]
}

现在我需要检查单个数组,如果第一个最后一个索引是否与其他其他数组一起,如果是,则需要查看最大值和最小值。如果没有那么需要分别将这个特定的数组最大和最小化。对于上面的对象,下面应该是我的输出...

{   
    "dataarray-345":
    [
        {lqd: 1000, date: "2017-08-18 09:30:00"},
        {lqd: 3500, date: "2017-08-18 12:30:00"}
    ],
    "dataarray-123":
    [
        {lqd: 1000, date: "2017-08-18 09:30:00"},
        {lqd: 3500, date: "2017-08-18 12:30:00"}
    ],
    "dataarray-127":
    [
        {lqd: 8500, date: "2017-08-18 13:00:00"},
        {lqd: 6500, date: "2017-08-18 14:00:00"}
    ]
}

可以在javascript中使用吗?什么可能是在JavaScript中的方式?你能帮我吗?

1 个答案:

答案 0 :(得分:0)

边缘有点粗糙,没有时间添加评论和优化,但它确实有效。

该片段的日志有点奇怪,但是当您打开开发工具时,您将看到预期的输出。

const 
  SpecialObj = {   
      "dataarray-345":
      [
          {lqd: 1000, date: "2017-08-18 09:30:00"},
          {lqd: 5000, date: "2017-08-18 10:00:00"},
          {lqd: 5500, date: "2017-08-18 10:30:00"},
          {lqd: 4500, date: "2017-08-18 11:00:00"},
          {lqd: 1500, date: "2017-08-18 11:30:00"}
      ],
      "dataarray-123":
      [

          {lqd: 5000, date: "2017-08-18 10:00:00"},
          {lqd: 5500, date: "2017-08-18 10:30:00"},
          {lqd: 4500, date: "2017-08-18 11:00:00"},
          {lqd: 1500, date: "2017-08-18 11:30:00"},
          {lqd: 2500, date: "2017-08-18 12:00:00"},
          {lqd: 3500, date: "2017-08-18 12:30:00"}
      ],
      "dataarray-127":
      [
          {lqd: 8500, date: "2017-08-18 13:00:00"},
          {lqd: 9500, date: "2017-08-18 13:30:00"},
          {lqd: 6500, date: "2017-08-18 14:00:00"}
      ]
  };
  
/**
 * Creates a reverse lookup object. For each unique lqd value it will list the 
 * keys that contain the lqd value.
 *
 * @param {Object} input  The input object to create a reverse lookup for.
 *
 * @returns {Object} An object where each unique lqd value is a property with 
 *          it's value an array of object keys.
 */
function getReverseLookupObject(input) {
  // Create the result object.
  const
    result = Object.create(null);
    
  // Iterate over the object properties.
  for (let key in input) {
    // When the current property is from the prototype chain we will skip it.
    if (!input.hasOwnProperty(key)) {
      continue;
    }
    
    // Iterate over all the items in the array that is stored under the property.
    input[key].forEach(item => {
      // Check if the current lqd is not yet in the result.
      if (result[item.lqd] === undefined) {
        // Create a property for the lqd value and assign it an array with the current key.
        result[item.lqd] = [key];
      } else {
        // Add the current key to the array.
        result[item.lqd].push(key);
      }
    });
  }
  
  // Return the reverse lookup object.
  return result;
}

/**
 * Returns an array with two items. The item at index 0 will be the item with the 
 * earliest date. Index 1 will contain the item with the latest date.
 *
 * @param {Array} array  The array with source items.
 *
 * @returns {Array} An array with the items that have the earliest and latest date.
 */
function getMinMax(array) {
  // Sort the source array by date property, ascending.
  array.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime());
  
  // Return an array with the first and last item in the sorted array.
  return [
    array[0],
    array[array.length - 1]
  ]
}

/**
 * Returns a set of properties in the original input object that contain the
 * lqd of either the first or last item in the array.
 */
function getParentKeys(reverseLookupObject, keyValues) {
  const
    // Get last index if the keyValue array.
    lastIndex = keyValues.length - 1,
    // Get the array with keys that contain the lqd for the 1st item.
    firstElementParents = reverseLookupObject[keyValues[0].lqd],
    // Get the array with keys that contain the lqd for the last item.    
    lastElementParents = reverseLookupObject[keyValues[lastIndex].lqd];
    
  // Create a set of the keys. This has the benefit that duplicate keys will
  // be removed. When the first and last element both have the same parent the
  // resulting set will only contain that parent once.
  return new Set([...firstElementParents, ...lastElementParents]);
}

function transformData(input) {
  const
    // Create the reverse lookup object.
    reverseLookup = getReverseLookupObject(input),
    // Initialize the result.
    result = Object.create(null);
  
  // Iterate over the properties of the input object.
  for (let key in input) {
    // When the property if from the prototype chain we can skip it.
    if (!input.hasOwnProperty(key)) {
      continue;
    }
    
    const
      // Get the input object properties that contain the lqd of the first and last items.
      parentKeys = getParentKeys(reverseLookup, input[key]);
    let
      combinedItems = [];
    // Iterate over the parents and combine all their values into a single array.
    parentKeys.forEach(parentKey => combinedItems = [...combinedItems, ...input[parentKey]]);
    
    // Add the current key in the result with the items that have the earliest and 
    // latest date.
    result[key] = getMinMax(combinedItems);
  }
  return result;
}

console.log(transformData(SpecialObj));