kabeer rifaye
kabeer rifaye

Reputation: 417

Iterate and group the objects using map function

Check for the decimal id and group them accordingly.

Below are the sample and recommended JSON's

Sample JSON

{
    "results": [
        {
            "name": "Download",
            "id": "1.1.1"
        },
        {
            "name": "Download",
            "id": "1.2"
        },
        {
            "name": "Download",
            "id": "1.3.2"
        },
        {
            "name": "Download",
            "id": "2"
        },
        {
            "name": "Download",
            "id": "2.3"
        },
        {
            "name": "Download",
            "id": "3.2"
        },
        {
            "name": "Download",
            "id": "3.5"
        },
        {
            "name": "Download",
            "id": "4.2"
        }
    ]
}

Would like to iterate and Re-structure the above JSON into below recommended format.

Logic: Should check the id(with and without decimals) and group them based on the number.

For Example:

1, 1.1, 1.2.3, 1.4.5 => data1: [{id: 1},{id: 1.1}....] 
2, 2.3, 2.3.4 => data2: [{id: 2},{id: 2.3}....]
3, 3.1 => data3: [{id: 3},{id: 3.1}]

Recommended JSON

{
    "results": [
        {
            "data1": [
                {
                    "name": "Download",
                    "id": "1.1.1"
                },
                {
                    "name": "Download",
                    "id": "1.2"
                },
                {
                    "name": "Download",
                    "id": "1.3.2"
                }
            ]
        },
        {
            "data2": [
                {
                    "name": "Download",
                    "id": "2"
                },
                {
                    "name": "Download",
                    "id": "2.3"
                }
            ]
        },
        {
            "data3": [
                {
                    "name": "Download",
                    "id": "3.2"
                },
                {
                    "name": "Download",
                    "id": "3.5"
                }
            ]
        },
        {
            "data4": [
                {
                    "name": "Download",
                    "id": "4.2"
                }
            ]
        }
    ]
}

I have tried the below solution but it doesn't group the object

var formatedJSON = [];
results.map(function(d,i) {
    formatedJSON.push({
        [data+i]: d
    })
});

Thanks in advance.

Upvotes: 2

Views: 946

Answers (5)

Sumer
Sumer

Reputation: 2867

One solution with RegEx for finer control as it would differentiate easily between 1 and 11. Also this will make sure that even if the same version comes in end(say 1.9 in end) it will put it back in data1.

let newArr2 = ({ results }) =>
  results.reduce((acc, item) => {
    let key = "data" + /^(\d+)\.?.*/.exec(item.id)[1];
    let found = acc.find(i => key in i);
    found ? found[key].push(item) : acc.push({ [key]: [item] });
    return acc;
  }, []);

Upvotes: 0

Mohammed Ashfaq
Mohammed Ashfaq

Reputation: 3426

let input = getInput();

let output = input.reduce((acc, curr)=>{
  let {id} = curr;
  let majorVersion = 'name' + id.split('.')[0];
  if(!acc[majorVersion]) acc[majorVersion]= [];
  acc[majorVersion].push(curr);
  return acc;
},{})
  
console.log(output)
  
  
  
function getInput(){
  return [
  {
      "name": "Download",
      "id": "1.1.1"
  },
  {
      "name": "Download",
      "id": "1.2"
  },
  {
      "name": "Download",
      "id": "1.3.2"
  },
  {
      "name": "Download",
      "id": "2"
  },
  {
      "name": "Download",
      "id": "2.3"
  },
  {
      "name": "Download",
      "id": "3.2"
  },
  {
      "name": "Download",
      "id": "3.5"
  },
  {
      "name": "Download",
      "id": "4.2"
  }

  ]
  }

Upvotes: 0

adiga
adiga

Reputation: 35253

You can use reduce like this. The idea is to create a key-value pair for each data1, data2 etc so that values in this object are the values you need in the final array. Then use Object.values to get those as an array.

const sampleJson = {"results":[{"name":"Download","id":"1.1.1"},{"name":"Download","id":"1.2"},{"name":"Download","id":"1.3.2"},{"name":"Download","id":"2"},{"name":"Download","id":"2.3"},{"name":"Download","id":"3.2"},{"name":"Download","id":"3.5"},{"name":"Download","id":"4.2"}]}

const grouped = sampleJson.results.reduce((a, v) => {
    const key = `data${parseInt(v.id)}`;
    (a[key] = a[key] || {[key]: []})[key].push(v);
    return a;
},{});

console.log({results: Object.values(grouped)})

One liner / Code-golf:

let s={"results":[{"name":"Download","id":"1.1.1"},{"name":"Download","id":"1.2"},{"name":"Download","id":"1.3.2"},{"name":"Download","id":"2"},{"name":"Download","id":"2.3"},{"name":"Download","id":"3.2"},{"name":"Download","id":"3.5"},{"name":"Download","id":"4.2"}]},k;

console.log({results:Object.values(s.results.reduce((a,v)=>(k=`data${parseInt(v.id)}`,(a[k] = a[k]||{[k]:[]})[k].push(v),a),{}))})

Upvotes: 2

Jack Bashford
Jack Bashford

Reputation: 44125

Here's how you'd do it:

var data = {
    "results": [
        {
            "name": "Download",
            "id": "1.1.1"
        },
        {
            "name": "Download",
            "id": "1.2"
        },
        {
            "name": "Download",
            "id": "1.3.2"
        },
        {
            "name": "Download",
            "id": "2"
        },
        {
            "name": "Download",
            "id": "2.3"
        },
        {
            "name": "Download",
            "id": "3.2"
        },
        {
            "name": "Download",
            "id": "3.5"
        },
        {
            "name": "Download",
            "id": "4.2"
        }
    ]
};

var newData = {
  "results": {}
};

data.results.forEach(item => {
  var num = item.id.slice(0, 1);
  if (newData.results["data" + num]) {
    newData.results["data" + num].push(item);
  } else {
    newData.results["data" + num] = [item];
  }
})

data = newData;
console.log(data);

What this does is it iterates through each item in results, gets the number at the front of this item's id, and checks if an array of the name data-{num} exists. If the array exists, it's pushed. If it doesn't exist, it's created with the item.

Upvotes: 0

Bibberty
Bibberty

Reputation: 4768

Here you go:

var data = {
    "results": [
        {
            "name": "Download",
            "id": "1.1.1"
        },
        {
            "name": "Download",
            "id": "1.2"
        },
        {
            "name": "Download",
            "id": "1.3.2"
        },
        {
            "name": "Download",
            "id": "2"
        },
        {
            "name": "Download",
            "id": "2.3"
        },
        {
            "name": "Download",
            "id": "3.2"
        },
        {
            "name": "Download",
            "id": "3.5"
        },
        {
            "name": "Download",
            "id": "4.2"
        }
    ]
};


let newSet = new Set();

data.results.forEach(e => {
  let key = e.id.substring(0, e.id.indexOf('.'));
  console.log(key);
  if (newSet.has(key) == false) {
    newSet.add(key);
    newSet[key] = [];
    }
   newSet[key].push(e.id);
});


console.log(newSet);

Upvotes: 0

Related Questions