skip to Main Content

I want to set value to array if name have index, I have data like this:

[
    {
        "column": "created_at[0]",
        "name": "created_at[0]",
        "type": "range",
        "value": "2022-12-26 00:00:00"
    },
    {
        "column": "created_at[1]",
        "name": "created_at[1]",
        "type": "range",
        "value": "2023-12-26 23:59:59"
    },
    {
        "column": "email",
        "name": "email",
        "type": "like",
        "value": "[email protected]"
    }
]

and I want to modify the name and value to array result if name have index, the result should like this:

[
    {
        "column": "created_at",
        "name": "created_at",
        "type": "range",
        "value": ["2022-12-12 00:00:00", "2023-12-12 23:59:59"]
    },
    {
        "column": "email",
        "name": "email",
        "type": "like",
        "value": "[email protected]"
    }
]

I have try to do that whit this, but it doest work

const res = array?.reduce(
      (accumulator, value) => ({
        ...accumulator,
        [value.name?.split("[").shift()]: value.value,
      }),
      {}
    );
    console.log(res)

3

Answers


  1. Something like this – note the Nullish coalescing assignment ??=

    const grouped = array.reduce((acc, { name, value }) => {
      const baseName = name.split('[')[0];
      acc[baseName] ??= { // using the Nullish coalescing assignment
        column: baseName,
        name: baseName,
        type: name.includes('[') ? 'range' : 'like',
        value: []
      };
      
      if (name.includes('[')) { // it's a range
        acc[baseName].value.push(value);
      } else {
        acc[baseName].value = value;
      }
    
      return acc;
    }, {});
    
    const result = Object.values(grouped);
    console.log(result);
    <script>
      const array = [{
          "column": "created_at[0]",
          "name": "created_at[0]",
          "type": "range",
          "value": "2022-12-26 00:00:00"
        },
        {
          "column": "created_at[1]",
          "name": "created_at[1]",
          "type": "range",
          "value": "2023-12-26 23:59:59"
        },
        {
          "column": "email",
          "name": "email",
          "type": "like",
          "value": "[email protected]"
        }
      ]; </script>

    Faster example?

    const grouped = array.reduce((acc, { name, value }) => {
      const splitIndex = name.indexOf('[');
      const baseName = splitIndex === -1 ? name : name.substring(0, splitIndex);
      const isRange = splitIndex !== -1;
    
      let entry = acc[baseName];
      if (!entry) {
        entry = acc[baseName] = {
          column: baseName,
          name: baseName,
          type: isRange ? 'range' : 'like',
          value: isRange ? [] : value
        };
      }
    
      if (isRange) {
        entry.value.push(value);
      }
    
      return acc;
    }, {});
    
    console.log(grouped)
    <script>
      const array = [{
          "column": "created_at[0]",
          "name": "created_at[0]",
          "type": "range",
          "value": "2022-12-26 00:00:00"
        },
        {
          "column": "created_at[1]",
          "name": "created_at[1]",
          "type": "range",
          "value": "2023-12-26 23:59:59"
        },
        {
          "column": "email",
          "name": "email",
          "type": "like",
          "value": "[email protected]"
        }
      ];
    </script>
    Login or Signup to reply.
  2. const data = [
        {
            "column": "created_at[0]",
            "name": "created_at[0]",
            "type": "between",
            "value": "2022-12-26 00:00:00"
        },
        {
            "column": "created_at[1]",
            "name": "created_at[1]",
            "type": "between",
            "value": "2023-12-26 23:59:59"
        },
        {
            "column": "email",
            "name": "email",
            "type": "like",
            "value": "[email protected]"
        }
    ];
    
    const result = data.reduce((r, item) => {
      const idx = item.name.lastIndexOf('[');
      if (idx === -1) return r.arr.push(item) && r;
      const name = item.name.slice(0, idx);
      let found = r.map[name];
      found ? r.arr.push({column: name, name, type: 'range', value: [found.value, item.value]}) : r.map[name] = item;
      return r;
    }, {arr: [], map: {}}).arr;
    
    console.log(result);
    ` Chrome/120
    -----------------------------------------------------------------
    Alexander             1.00x  |  x1000000  123  124  129  130  131
    mplungjan             1.18x  |  x1000000  145  147  150  150  150
    mplungjan (faster?)   1.35x  |  x1000000  166  167  175  176  186
    -----------------------------------------------------------------
    https://github.com/silentmantra/benchmark `
    
    ` Firefox/121
    ------------------------------------------------------------------
    Alexander             1.00x  |  x10000000  729  753  784  799  801
    mplungjan (faster?)   1.55x  |   x1000000  113  118  122  132  146
    mplungjan             3.42x  |   x1000000  249  261  262  263  267
    ------------------------------------------------------------------
    https://github.com/silentmantra/benchmark `
    
    const data = [
        {
            "column": "created_at[0]",
            "name": "created_at[0]",
            "type": "between",
            "value": "2022-12-26 00:00:00"
        },
        {
            "column": "created_at[1]",
            "name": "created_at[1]",
            "type": "between",
            "value": "2023-12-26 23:59:59"
        },
        {
            "column": "email",
            "name": "email",
            "type": "like",
            "value": "[email protected]"
        }
    ];
    
    // @benchmark mplungjan 
    
    const grouped = data.reduce((acc, { name, value }) => {
      const baseName = name.split('[')[0];
      acc[baseName] ??= {
    column: baseName,
    name: baseName,
    type: name.includes('[') ? 'range' : 'like',
    value: []
      };
      
      if (name.includes('[')) { // it's a range
    acc[baseName].value.push(value);
      } else {
    acc[baseName].value = value;
      }
    
      return acc;
    }, {});
    
    Object.values(grouped);
    
    // @benchmark mplungjan (faster?)
    
    Object.values(data.reduce((acc, { name, value }) => {
      const splitIndex = name.indexOf('[');
      const baseName = splitIndex === -1 ? name : name.substring(0, splitIndex);
      const isRange = splitIndex !== -1;
    
      let entry = acc[baseName];
      if (!entry) {
    entry = acc[baseName] = {
      column: baseName,
      name: baseName,
      type: isRange ? 'range' : 'like',
      value: isRange ? [] : value
    };
      }
    
      if (isRange) {
    entry.value.push(value);
      }
    
      return acc;
    }, {}));
    
    // @benchmark Alexander
    
    data.reduce((r, item) => {
      const idx = item.name.lastIndexOf('[');
      if (idx === -1) return r.arr.push(item) && r;
      const name = item.name.slice(0, idx);
      let found = r.map[name];
      found ? r.arr.push({column: name, name, type: 'range', value: [found.value, item.value]}) : r.map[name] = item;
      return r;
    }, {arr: [], map: {}}).arr;
    
    /*@end*/eval(atob('e2xldCBlPWRvY3VtZW50LmJvZHkucXVlcnlTZWxlY3Rvcigic2NyaXB0Iik7aWYoIWUubWF0Y2hlcygiW2JlbmNobWFya10iKSl7bGV0IHQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7dC5zcmM9Imh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9naC9zaWxlbnRtYW50cmEvYmVuY2htYXJrL2xvYWRlci5qcyIsdC5kZWZlcj0hMCxkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHQpfX0='));
    Login or Signup to reply.
  3. const data = [{
        "column": "created_at[0]",
        "name": "created_at[0]",
        "type": "between",
        "value": "2022-12-26 00:00:00"
      },
      {
        "column": "created_at[1]",
        "name": "created_at[1]",
        "type": "between",
        "value": "2023-12-26 23:59:59"
      },
      {
        "column": "email",
        "name": "email",
        "type": "like",
        "value": "[email protected]"
      }
    ];
    
    const res = data.reduce((accumulator, item) => {
      const nameParts = item.name.split("[");
      const baseName = nameParts[0];
    
      if (nameParts.length > 1) {
        const index = parseInt(nameParts[1].replace("]", ""));
        if (!accumulator[baseName]) {
          accumulator[baseName] = {
            column: baseName,
            name: baseName,
            type: "range",
            value: Array(index + 1).fill(null).map(() => null)
          };
        }
        accumulator[baseName].value[index] = item.value;
      } else {
        accumulator[baseName] = { ...item
        };
      }
    
      return accumulator;
    }, {});
    
    const resultArray = Object.values(res);
    console.log(resultArray);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search