Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Сформировать массив объектов (https://javascript.ru/forum/misc/77606-sformirovat-massiv-obektov.html)

Castromen 26.05.2019 13:05

Сформировать массив объектов
 
Добрый день, подскажите плз. как сформировать массив объектов с определенной логикой



1. Имеется Obj со структурой:

"user 1": {
       company : 'Рога и копыта'
       name : 'Александр',
       projects : {
             projectID1 : {
                   role_right: 0
             }
       }
  },
 "user 2": {
       company : 'Копыта и рога',
       name : 'Петя',
       projects : {
             projectID1 : {
                   role_right: 0
             }
       }
  },
  "user 3": {
       role_right: 1,
       company : 'Копыта и рога',
       name : 'Василий',
       projects : {
             projectID1 : {
                   role_right: 2
             }
       }

  },
  ....
}

На выходе хотелось бы получить массив объектов сгруппированные по ключу company и внутри company отсортированы по ключу с role_right.

[
    {title: 'Рога и копыта', data: [
    {
       role_right: 0,
       company : 'Рога и копыта'
       name : 'Александр'
     }
    ]},
    {title: 'Копыта и рога', data: [
    {
       role_right: 0,
       company : 'Копыта и рога'
       name : 'Петя'
     },
     {
       role_right: 2,
       company : 'Копыта и рога'
       name : 'Василий'
     },

    ]},
    .....
  ]


Спасибо.

Malleys 26.05.2019 14:03

var data = {
	"user 1": {
		company: 'Рога и копыта',
		name: 'Александр',
		projects: {
			projectID1: {
				role_right: 0
			}
		}
	},
	"user 2": {
		company: 'Копыта и рога',
		name: 'Петя',
		projects: {
			projectID1: {
				role_right: 0
			}
		}
	},
	"user 3": {
		company: 'Копыта и рога',
		name: 'Василий',
		projects: {
			projectID1: {
				role_right: 2
			}
		}
	},
};

var temp = Object.values(data).reduce((object, user) => {
	if(user.company in object === false) {
		object[user.company] = {
			title: user.company,
			data: []
		};
	}

	object[user.company].data.push(user);

	return object;
}, {});

var newData = Object.values(temp).map(company => {
	company.data.sort((a, b) => a.projects.projectID1.role_right > b.projects.projectID1.role_right ? 1 : -1);

	company.data = company.data.map(user => {
		user.role_right = user.projects.projectID1.role_right;
		delete user.projects; // возможно не надо удалить?
		return user;
	});
	return company;
});

console.log(newData);

рони 26.05.2019 14:47

Malleys,
company.data.sort((a, b) => a.projects.projectID1.role_right - b.projects.projectID1.role_right );

рони 26.05.2019 16:35

Castromen,
var data = {
	"user 1": {
		company: 'Рога и копыта',
		name: 'Александр',
		projects: {
			projectID1: {
				role_right: 0
			}
		}
	},
	"user 2": {
		company: 'Копыта и рога',
		name: 'Петя',
		projects: {
			projectID1: {
				role_right: 0
			}
		}
	},
	"user 3": {
		company: 'Копыта и рога',
		name: 'Василий',
		projects: {
			projectID1: {
				role_right: 2
			}
		}
	},
    "user 4": {
		company: 'Копыта и рога',
		name: 'Иван',
		projects: {
			projectID1: {
				role_right: 1
			}
		}
	}
};

var newData = Object.values(data).reduce(function(object, user) {
    var obj = {
            role_right: user.projects.projectID1.role_right,
            company: user.company,
            name: user.name
        },
        item;
    if (user.company in object === false) {
        item = {
            title: user.company,
            data: [obj]
        };
        object[user.company] = item.data;
        object.newData.push(item)
    } else {
        var arr = object[user.company];
        for (var i = arr.length - 1; i ; i--) {
            item = arr[i];
            if (item.role_right < obj.role_right) break;
        }
        arr.splice(++i, 0, obj)
    }
    return object
}, {newData: []}).newData;

console.log(newData);

Alexandroppolus 26.05.2019 18:18

рони, зачем сортировка вставками? )

var data = {
    "user 1": {
        company: 'Рога и копыта',
        name: 'Александр',
        projects: {
            projectID1: {
                role_right: 0
            }
        }
    },
    "user 2": {
        company: 'Копыта и рога',
        name: 'Петя',
        projects: {
            projectID1: {
                role_right: 0
            }
        }
    },
    "user 3": {
        company: 'Копыта и рога',
        name: 'Василий',
        projects: {
            projectID1: {
                role_right: 2
            }
        }
    }
};


var newData = Object.keys(data).reduce(function(r, userId) {
    var user = data[userId];
    var company = r.map[user.company];
    if (!company) {
        company = r.map[user.company] = {
            title: user.company,
            data: []
        };
        r.arr.push(company);
    }
    company.data.push({
        role_right: user.projects.projectID1.role_right,
        company : user.company,
        name : user.name
    });
    return r;
}, { arr: [], map: Object.create(null) }).arr;

newData.forEach(function (item) {
    item.data.sort(function(a, b) { return a.role_right - b.role_right; });
});

alert(JSON.stringify(newData, '', 4));

рони 26.05.2019 18:24

Цитата:

Сообщение от Alexandroppolus
зачем сортировка вставками?

а вдруг быстрее?

Alexandroppolus 26.05.2019 18:29

Цитата:

Сообщение от рони (Сообщение 508377)
а вдруг быстрее?

Если объектов мало, то да, вставки быстрее чем быстрая сортировка. В этом случае и обычный [].sort делается вставками. Но на перспективу однозначно медленнее.
Возможно, будет небольшой выигрыш, если фирм дохренища, а юзеров в фирмах, немного, в пределах 10. Хотя опять же не факт, нативный sort может быть побыстрее js-ного цикла

Castromen 26.05.2019 19:23

Коллеги, спасибо большое!!!
Теперь я хочу отсорировать объект newData по компании т.е если компания "Копыта и рога" всегда будет в массиве первая

newData.sort((a, b) => {
                const genreA = a.company
                const genreB = b.company

                let comparison = 0;
                if (genreA ===  "Копыта и рога") {
                    comparison = 1;
                }
                return comparison;
            });


Но пока без результатного

рони 26.05.2019 19:40

Castromen,
let comparison = -1;

Alexandroppolus 26.05.2019 19:52

Цитата:

Сообщение от Castromen
компания "Копыта и рога" всегда будет в массиве первая

newData.sort(function (a, b) {
    var wa = a.title === 'Копыта и рога' ? 0 : 1;
    var wb = b.title === 'Копыта и рога' ? 0 : 1;
    return wa - wb;
});


Часовой пояс GMT +3, время: 11:54.