Cele King
Cele King

Reputation: 95

how to push the elements that have the same property value in an Array as a element into a new Array?

I am trying to put the elements that have the same property value in Array(e.g., data) in a group as a new element and push the new element into a new Array(e.g., newData). How can I transform data to newData ?

data = [
    {status: 0,name:'a'},
    {status: 0,name:'b'},
    {status: 1,name:'b'},
];

var newData = [
           {
               id: 0,
                name: 'a',
                    services: [
                        {id: 'a', name: 'a',status: 0}
                    ]
                },
                {
                    id: 1,
                    name: 'b',
                    services: [
                        {id: 'b', name: 'b',status: 0},
                        {id: 'b', name: 'b',status: 1},
                    ]
                }
            ]

Upvotes: 0

Views: 141

Answers (5)

Nina Scholz
Nina Scholz

Reputation: 386654

You could use a hash table as reference to the group with the same name and push the actual item to services.

var data = [{ status: 0, name: 'a' }, { status: 0, name: 'b' }, { status: 1, name: 'b' }],
    grouped = data.reduce(function (hash) {
        return function (r, a) {
            if (!hash[a.name]) {
                hash[a.name] = { id: a.name, name: a.name, services: [] };
                r.push(hash[a.name]);
            }
            a.id = a.name;
            hash[a.name].services.push(a);
            return r;
        };
    }(Object.create(null)), []);

console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

With id counting from zero.

var data = [{ status: 0, name: 'a' }, { status: 0, name: 'b' }, { status: 1, name: 'b' }],
    grouped = data.reduce(function (hash, id) {
        return function (r, a) {
            if (!hash[a.name]) {
                hash[a.name] = { id: id++, name: a.name, services: [] };
                r.push(hash[a.name]);
            }
            a.id = a.name;
            hash[a.name].services.push(a);
            return r;
        };
    }(Object.create(null), 0), []);

console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 5

dev8080
dev8080

Reputation: 4020

var data = [
             {status: 0,name:'a'},
             {status: 0,name:'b'},
             {status: 1,name:'b'}
         ];
var finalData = [];
var i=0;
data.forEach(function(datum){
                           var matchingElem = finalData.find(function(elem){
                           return elem.name === datum.name;
             });

if(matchingElem) 
  {
    matchingElem.services.push({
                        "id":datum.name,
                        "name": datum.name,
                        "status": datum.status
                      });
  }
  else{
           finalData.push({
                      "id":i++,
                      "name":datum.name,
                      "services": [{
                                 "id":datum.name,
                                 "name": datum.name,
                                 "status": datum.status
                               }]
                    });
     }

});
console.log(JSON.stringify( finalData ));

Upvotes: 3

RaR
RaR

Reputation: 3213

    var data = [
        {status: 0,name:'a'},
        {status: 0,name:'b'},
        {status: 1,name:'b'},
    ];

    var id = 0;
    var finalData = data.reduce(function(acc, cur) {
      var elm = acc.find(e => {
        return e.name === cur.name
      });
      if (elm) {
        elm.services.push({
          id: cur.name,
          name: cur.name,
          status: cur.status
        })
      } else {
        acc.push({
          id: id++,
          name: cur.name,
          services: [{
            id: cur.name,
            name: cur.name,
            status: cur.status
          }]
        })
      }
      return acc;
    }, []);
    
    console.log(finalData)

Upvotes: 1

gurvinder372
gurvinder372

Reputation: 68393

Follow this approach

  • Create a map of name and array of statuses against it.
  • iterate the map and prepare the array.

DEMO

var data = [
    {status: 0,name:'a'},
    {status: 0,name:'b'},
    {status: 1,name:'b'},
];

var map = {};
data.forEach( function(item){
 map[ item.name ] = map[ item.name ] || [];
 map[ item.name ].push( item );
});

var newData = Object.keys( map ).map(function(name, index){
  var arr = map[ name ];
  arr = arr.map( function(arrItem){ arrItem.id = arrItem.name; return arrItem });
  return { id : index, name : name, services : arr };
});

console.log(newData);

Upvotes: 1

Jonas Wilms
Jonas Wilms

Reputation: 138317

data = [
{status: 0,name:'a'},
{status: 0,name:'b'},
{status: 1,name:'b'}, 
];

NewData=data.reduce((newobj,obj)=>((newobj[obj.name]=newobj[obj.name]||[]).push(obj),newobj),{});

NewData will be:

{
    "a":[
      {status: 0,name:'a'},
    ],
    "b":[
      {status: 0,name:'b'},
      {status: 1,name:'b'}, 
    ]
}

http://jsbin.com/devucujaso/edit?console

You simply put every obj of the old array into the obj.name Array of the new obj, if it doesnt exist yet create a new array ( ||[]). Theres still some forming missing to get your desired result, but i think you can do that on your own...

Upvotes: 2

Related Questions