循环对象数组并根据比较对象值获取新对象

时间:2021-02-28 13:30:45

标签: javascript arrays javascript-objects

我的状态中有这个数组:

[
  {
    id: "17CVqaiM",
    styles: {
      desktop: {
        height: 163,
        width: 163,
        left: 498,
        top: 350
      },
      mobile: {
        height: 150,
        width: 150,
        left: 135,
        top: 205
      }
    }
  },
  {
    id: "xL-4vIfV",
    styles: {
      desktop: {
        height: 150,
        width: 150,
        left: 675,
        top: 91
      },
      mobile: {
        height: 150,
        width: 150,
        left: 105,
        top: 175
      }
    }
  }
];

如何根据样式键和设备类型(桌面或移动设备)循环遍历它,比较它们的值,然后获取具有这些属性的对象?

{
  [desktop || mobile]: {
    // the formula for desktop or mobile is the same. only the styles objects is different
    top: "least top value in desktop styles objects",
    left: "least left value in desktop styles objects",
    width: "(most left value in desktop styles objects + that object width) - least left value in desktop styles objects",
    height: "(most top value in desktop styles objects + that object height) - least top value in desktop styles objects"
  }
}

我尝试使用这个 reduce 函数,但无法正确解决。

array.reduce((prev, current) => {
  const top = {
    prev: prev.styles[device].top,
    current: current.styles[device].top
  };
  const left = {
    prev: prev.styles[device].left,
    current: current.styles[device].left
  };
  const width = {
    prev: prev.styles[device].width,
    current: current.styles[device].width
  };
  const height = {
    prev: prev.styles[device].height,
    current: current.styles[device].height
  };

  return {
    [device]: {
      top: (top.prev < top.current ? top.prev : top.current) + "px",
      left: (left.prev < left.current ? left.prev : left.current) + "px",
      width: (left.prev > left.current
          ? left.prev + width.prev - left.current
          : left.current + width.current - left.prev) + "px",
      height: (top.prev > top.current
          ? top.prev + height.prev
          : top.current + height.current) -
        (top.prev < top.current ? top.prev : top.current) + "px"
    }
  };
});

这只适用于数组中的 2 个项目,而不适用于更多。

2 个答案:

答案 0 :(得分:0)

px 中返回时不要连接 reduce,您可以准确比较。 试试这个:

const result = array.reduce((acc, cur) => {
  const top = {
    acc: acc[device].top,
    cur: current.styles[device].top,
  }
  // ...
  return {
    [device]: {
      top: top.acc < top.cur ? top.acc : top.cur,
      // ...
    }
  }
}, {
  [device]: {
    top: 0,
    left: 0,
    width: 0,
    height: 0,
  }
})

array[device].top += 'px'
// ...

答案 1 :(得分:0)

问题

根据 styles 键和 device type 比较两个对象(例如移动设备或桌面设备)

您的代码

const compareObj = ((prev, current) => {
  const top = {
      prev: prev.styles[device].top,
      current: current.styles[device].top,
  };
  const left = {
      prev: prev.styles[device].left,
      current: current.styles[device].left,
  };
  const width = {
      prev: prev.styles[device].width,
      current: current.styles[device].width,
  };
  const height = {
      prev: prev.styles[device].height,
      current: current.styles[device].height,
  };

  return {
      top: (top.prev < top.current ? top.prev : top.current) + 'px',
      left: (left.prev < left.current ? left.prev : left.current) + 'px',
      width: (left.prev > left.current
              ? left.prev + width.prev - left.current
              : left.current + width.current - left.prev) + 'px',
      height: (top.prev > top.current
              ? top.prev + height.prev
              : top.current + height.current) -
          (top.prev < top.current ? top.prev : top.current) + 'px',
  };
});

const dummies = [
  {
    id: "17CVqaiM",
    styles: {
      desktop: {
        height: 163,
        width: 163,
        left: 498,
        top: 350
      },
      mobile: {
        height: 150,
        width: 150,
        left: 135,
        top: 205
      }
    }
  },
  {
    id: "xL-4vIfV",
    styles: {
      desktop: {
        height: 150,
        width: 150,
        left: 675,
        top: 91
      },
      mobile: {
        height: 150,
        width: 150,
        left: 105,
        top: 175
      }
    }
  }
];

console.log(compareObj(dummies[0], dummies[1]));

您的代码的结果

prev: prev.styles[device].top,
                        ^
ReferenceError: device is not defined

代码结果的原因

您从 device 对象调用了 styles 键,但它是未定义的值。

解决方案

您需要检查您调用的变量(或键)是否存在。

我的代码是

// the dummy data you will use
const dummies = [
  {
    id: "17CVqaiM",
    styles: {
      desktop: {
        height: 163,
        width: 163,
        left: 498,
        top: 350
      },
      mobile: {
        height: 150,
        width: 150,
        left: 135,
        top: 205
      }
    }
  },
  {
    id: "xL-4vIfV",
    styles: {
      desktop: {
        height: 150,
        width: 150,
        left: 675,
        top: 91
      },
      mobile: {
        height: 150,
        width: 150,
        left: 105,
        top: 175
      }
    }
  }
];

// function for comparing the style by device type
const compareStyles = (prev, current, deviceType) => {
  const prevDeviceStyle = prev.styles[deviceType];
  const currentDeviceStyle = current.styles[deviceType];

  // set variable combinedStyleObject for return 
  const combinedStyleObject = {};

  // compare prev and current style object with using for-in loop
  for (const eachProperty in prevDeviceStyle) {
    if (prevDeviceStyle[eachProperty] < currentDeviceStyle[eachProperty]) {
      combinedStyleObject[eachProperty] = `${prevDeviceStyle[eachProperty]}px`;
      continue;
    }
    combinedStyleObject[eachProperty] = `${currentDeviceStyle[eachProperty]}px`;
  }

  // return combinedStyleObject
  return combinedStyleObject;
};

// An array for your device type, to handle the case when you want to compare more device type.
// if you want to add more type such as 'tablet', just put it in this deviceTypes array!
const deviceTypes = ['mobile', 'desktop'];

// compare and reduce your style objects by device type!
const reducedStyles = deviceTypes.map(eachType => {
  return compareStyles(...dummies, eachType);
});

// check the result
console.log(JSON.stringify(reducedStyles));

输出

[
  { "height":"150px", "width":"150px", "left":"105px", "top":"175px" },
  { "height":"150px", "width":"150px", "left":"498px", "top":"91px" },
];

希望我的回答可以帮助您解决问题!

相关问题