簡體   English   中英

循環一個對象數組並根據比較對象值得到一個新的 object

[英]Loop an array of objects and get a new object based on comparing objects values

我的 state 中有這個數組:

[
  {
    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
      }
    }
  }
];

我如何遍歷它並基於 styles 密鑰和設備類型(台式機或移動設備),比較它們的值,然后獲得具有這些屬性的 object?

{
  [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"
  }
}

我嘗試使用這個減少 function 但無法正確解決。

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 個項目,而不是更多。

reduce中返回時不要連接px ,您可以精確比較。 嘗試這個:

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

問題

根據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

代碼結果的原因

您從styles object 調用了您的device密鑰,但它是未定義的值。

解決方案

您需要檢查您調用的變量(或鍵)是否存在。

我的代碼是

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

Output

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

希望我的回答對您的問題有所幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM