Home > Blockchain >  How can I write a beter way for iterate array in react
How can I write a beter way for iterate array in react

Time:01-11

I have a function which it iterate through an arrays to return a value base on condition. I used these:

export const DeviceCount = ({ home }: IDeviceCount) => {
  let sensorCount = 0;
  let hubcount = 0;

  if (home.rooms && home.rooms.length)
    home?.rooms.forEach(
      (home) =>
        home.nodes &&
        home?.nodes.forEach((node) => {
          if (["11", "12", "13", "14", "15"].includes(node?.type))
            sensorCount  ;
          else hubcount  ;
        })
    );

  return { sensorCount, hubcount };
};

I was looking for a better way for iterate through arrays .Because the above method is annoying.

But I want a better method.

thanks and regards

CodePudding user response:

If you can use optional chaining, then one of the bigger benefits of it is to access a possibly undefined nested property directly instead of testing if it exists first. Utilize it instead of testing the nested property in an earlier condition.

Also, because DeviceCount is not a component, it shouldn't start with a capital letter. It looks like it may be used as a custom hook, so consider renaming it to useDeviceCount.

export const useDeviceCount = ({ home }: IDeviceCount) => {
    let sensorCount = 0;
    let hubcount = 0;
    home?.rooms?.forEach((room) => {
        room?.nodes?.forEach((node) => {
            if (["11", "12", "13", "14", "15"].includes(node?.type)) {
                sensorCount  ;
            } else {
                hubcount  ;
            }
        });
    });
    return { sensorCount, hubcount };
};

(Check the IDeviceCount type. Does it really have so many possibly undefined nested properties? It seems strange - you may be able to get rid of a few of those optional chains.)

Another approach would be to map each room and node to a flat array of types first, then iterate over that.

export const useDeviceCount = ({ home }: IDeviceCount) => {
    let sensorCount = 0;
    let hubcount = 0;
    const nodeTypes = home?.rooms?.flatMap(
        room => room?.nodes?.map(node => node?.type)
    );
    for (const type of nodeTypes) {
        if (["11", "12", "13", "14", "15"].includes(type)) {
            sensorCount  ;
        } else {
            hubcount  ;
        }
    }
    return { sensorCount, hubcount };
};

CodePudding user response:

You could certainly optimise this somewhat.

For example, you could flatten the arrays and filter the result on a Set (for O(1) lookups)

const typeFilter = new Set(["11", "12", "13", "14", "15"]);

const nodeTypes =
  home.rooms?.flatMap((room) => room.nodes?.map(({ type }) => type) ?? []) ??
  [];

const sensorCount = nodeTypes.filter((type) => typeFilter.has(type)).length;
const hubcount = nodeTypes.length - sensorCount;

CodePudding user response:

Not sure how would you like to improve it, I would use two reduce to chain this function like this.

export const DeviceCount = ({ home }: IDeviceCount) => {
  return home?.rooms
    ?.reduce(
      (previousValue, home) =>
        home?.nodes ? [...previousValue, ...home?.nodes] : previousValue,
      []
    )
    .reduce(
      (previousValue, { hubcount, sensorCount }) =>
        ['11', '12', '13', '14', '15'].includes(node?.type)
          ? { hubcount, sensorCount: sensorCount   1 }
          : { hubcount: hubcount   1, sensorCount },
      { hubcount: 0, sensorCount: 0 }
    );
};

CodePudding user response:

You could create a set of all the sensor node types. Then, loop through the arrays and increment the appropriate variables conditionally. If you are using ?., you don't need to add the && checks. If the property being checked is nullish, the ?. will immediately return the nullish value and won't check access the further properties in the . chain

export const DeviceCount = ({ home }: IDeviceCount) => {
  let sensorCount = 0,
      hubcount = 0,
      sensorTypes = new Set(["11", "12", "13", "14", "15"]);

  home?.rooms?.forEach(room =>
    room?.nodes?.forEach(node =>
      sensorTypes.has(node.type) 
        ? sensorCount  
        : hubcount  ;
    )
  );

  return { sensorCount, hubcount };
};
  • Related