使用对象键对对象数组进行分组
Group array of objects with object keys
在原版中根据键对对象数组进行分组的最佳方法是什么 javascript,假设我有 10000 条记录,这是示例对象
[
{
company: "TATA",
car: "TATA Indica",
color: "Blue"
},
{
company: "TATA",
car: "TATA Indica",
color: "Black"
},
{
company: "TATA",
car: "Safari",
color: "Blue"
},
{
"company": "Suzuki",
car: "",
color: ""
}
]
预期输出为
{
"company": ["TATA", "Suzuki"],
"car": ["TATA Indica", "Safari"],
"color": ["Blue", "Black"]
}
你可以在这里使用reduce here, and to optimize it you can use Map。
const arr = [{
company: "TATA",
car: "TATA Indica",
color: "Blue",
},
{
company: "TATA",
car: "TATA Indica",
color: "Black",
},
{
company: "TATA",
car: "Safari",
color: "Blue",
},
{
company: "Suzuki",
car: "",
color: "",
},
];
const result = arr.reduce((acc, curr) => {
Object.keys(curr).forEach((k) => {
if (curr[k]) {
if (!acc[k]) acc[k] = new Set();
else acc[k].add(curr[k]);
}
});
return acc;
}, {});
Object.keys(result).forEach((k) => (result[k] = [...result[k]]));
console.log(result);
您可以使用 Set
来存储每个键的唯一值并稍后将它们转换回数组
const data = [
{
company: "TATA",
car: "TATA Indica",
color: "Blue",
},
{
company: "TATA",
car: "TATA Indica",
color: "Black",
},
{
company: "TATA",
car: "Safari",
color: "Blue",
},
{
company: "Suzuki",
car: "",
color: "",
},
]
let res = data.reduce((acc, el) => {
for (const [key, value] of Object.entries(el)) {
if (!value) continue
if (key in acc) {
const set = new Set(acc[key])
set.add(value)
acc[key] = Array.from(set)
} else {
acc[key] = [value]
}
}
return acc
}, {})
console.log(res)
对于原始值,您可以轻松使用 Set and Map 的组合。
您使用 Map
作为键,使用 Set
作为值。
const companies = ["TATA", "Suzuki", "Škoda", ""];
const cars = ["TATA Indica", "Safari", "Fabia", ""];
const colors = ["Blue", "Black", "Red", "Yellow", ""]
const arr = Array.from({length: 1000}, (v, i) => ({
company: companies[i % companies.length],
car: cars[i % cars.length],
color: colors[i % colors.length]
}));
console.time('Operation');
const map = new Map();
for(let item of arr) {
for(let key of Object.keys(item)){
let keySet = map.get(key);
if(!keySet){
keySet = new Set();
map.set(key, keySet);
}
const value = item[key];
if(value !== '') {
keySet.add(item[key]);
}
}
}
const result = {};
for(let key of map.keys()) {
result[key] = Array.from(map.get(key));
}
console.timeEnd('Operation');
console.log(result);
看起来您使用的数据始终具有稳定的形状。在这种情况下,您可以预先声明结果对象的形状,然后简单地将数据累加到其中,只检查非空值。这里使用Map and Set进行累加,然后映射到最终的结果对象。
const data = [{ company: 'TATA', car: 'TATA Indica', color: 'Blue' }, { company: 'TATA', car: 'TATA Indica', color: 'Black' }, { company: 'TATA', car: 'Safari', color: 'Blue' }, { company: 'Suzuki', car: '', color: '' },];
const map = new Map(Object.keys(data[0]).map((k) => [k, new Set()]));
for (const d of data) {
for (const k of map.keys()) {
if (d[k] !== '') {
map.get(k).add(d[k]);
}
}
}
const result = {};
for (const k of map.keys()) {
result[k] = Array.from(map.get(k));
}
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
奇怪的是,看似最幼稚的实现实际上证明相当高效(根据 @Totati's benchmark)。连续 map().filter()
次调用。
const data = [{ company: 'TATA', car: 'TATA Indica', color: 'Blue' }, { company: 'TATA', car: 'TATA Indica', color: 'Black' }, { company: 'TATA', car: 'Safari', color: 'Blue' }, { company: 'Suzuki', car: '', color: '' },];
const result = {};
for (const k of Object.keys(data[0])) {
result[k] = Array.from(
new Set(data.map(({ [k]: key }) => key).filter((n) => n !== ''))
);
}
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
在原版中根据键对对象数组进行分组的最佳方法是什么 javascript,假设我有 10000 条记录,这是示例对象
[
{
company: "TATA",
car: "TATA Indica",
color: "Blue"
},
{
company: "TATA",
car: "TATA Indica",
color: "Black"
},
{
company: "TATA",
car: "Safari",
color: "Blue"
},
{
"company": "Suzuki",
car: "",
color: ""
}
]
预期输出为
{
"company": ["TATA", "Suzuki"],
"car": ["TATA Indica", "Safari"],
"color": ["Blue", "Black"]
}
你可以在这里使用reduce here, and to optimize it you can use Map。
const arr = [{
company: "TATA",
car: "TATA Indica",
color: "Blue",
},
{
company: "TATA",
car: "TATA Indica",
color: "Black",
},
{
company: "TATA",
car: "Safari",
color: "Blue",
},
{
company: "Suzuki",
car: "",
color: "",
},
];
const result = arr.reduce((acc, curr) => {
Object.keys(curr).forEach((k) => {
if (curr[k]) {
if (!acc[k]) acc[k] = new Set();
else acc[k].add(curr[k]);
}
});
return acc;
}, {});
Object.keys(result).forEach((k) => (result[k] = [...result[k]]));
console.log(result);
您可以使用 Set
来存储每个键的唯一值并稍后将它们转换回数组
const data = [
{
company: "TATA",
car: "TATA Indica",
color: "Blue",
},
{
company: "TATA",
car: "TATA Indica",
color: "Black",
},
{
company: "TATA",
car: "Safari",
color: "Blue",
},
{
company: "Suzuki",
car: "",
color: "",
},
]
let res = data.reduce((acc, el) => {
for (const [key, value] of Object.entries(el)) {
if (!value) continue
if (key in acc) {
const set = new Set(acc[key])
set.add(value)
acc[key] = Array.from(set)
} else {
acc[key] = [value]
}
}
return acc
}, {})
console.log(res)
对于原始值,您可以轻松使用 Set and Map 的组合。
您使用 Map
作为键,使用 Set
作为值。
const companies = ["TATA", "Suzuki", "Škoda", ""];
const cars = ["TATA Indica", "Safari", "Fabia", ""];
const colors = ["Blue", "Black", "Red", "Yellow", ""]
const arr = Array.from({length: 1000}, (v, i) => ({
company: companies[i % companies.length],
car: cars[i % cars.length],
color: colors[i % colors.length]
}));
console.time('Operation');
const map = new Map();
for(let item of arr) {
for(let key of Object.keys(item)){
let keySet = map.get(key);
if(!keySet){
keySet = new Set();
map.set(key, keySet);
}
const value = item[key];
if(value !== '') {
keySet.add(item[key]);
}
}
}
const result = {};
for(let key of map.keys()) {
result[key] = Array.from(map.get(key));
}
console.timeEnd('Operation');
console.log(result);
看起来您使用的数据始终具有稳定的形状。在这种情况下,您可以预先声明结果对象的形状,然后简单地将数据累加到其中,只检查非空值。这里使用Map and Set进行累加,然后映射到最终的结果对象。
const data = [{ company: 'TATA', car: 'TATA Indica', color: 'Blue' }, { company: 'TATA', car: 'TATA Indica', color: 'Black' }, { company: 'TATA', car: 'Safari', color: 'Blue' }, { company: 'Suzuki', car: '', color: '' },];
const map = new Map(Object.keys(data[0]).map((k) => [k, new Set()]));
for (const d of data) {
for (const k of map.keys()) {
if (d[k] !== '') {
map.get(k).add(d[k]);
}
}
}
const result = {};
for (const k of map.keys()) {
result[k] = Array.from(map.get(k));
}
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
奇怪的是,看似最幼稚的实现实际上证明相当高效(根据 @Totati's benchmark)。连续 map().filter()
次调用。
const data = [{ company: 'TATA', car: 'TATA Indica', color: 'Blue' }, { company: 'TATA', car: 'TATA Indica', color: 'Black' }, { company: 'TATA', car: 'Safari', color: 'Blue' }, { company: 'Suzuki', car: '', color: '' },];
const result = {};
for (const k of Object.keys(data[0])) {
result[k] = Array.from(
new Set(data.map(({ [k]: key }) => key).filter((n) => n !== ''))
);
}
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }