如何在对象数组中获取具有唯一值的键? (JavaScript)
How can I get keys with unique values in an array of objects? (JavaScript)
我有一个包含两个值的对象数组:{path: '/index', ip: '123.456.789'}
有些路径是相同的,IP 也是如此。一些重复,一些独特的组合。
对于每个唯一路径,我想要附加到该路径的不同 ip 的数量。
因此,例如,可能有 15 个对象 path: '/index'
,但该路径只有 4 个唯一的 ip。
简单来说,我想查找特定网站页面的独立访问者数量。
希望这是有道理的,非常感谢
编辑:
到目前为止,这是我生成非唯一视图的方法:
export const generateViews = (viewData: string): Map<string, number> => {
const pathViewMap: Map<string, number> = new Map();
const viewDataArray = viewData.split("\n");
for (let i = 0; i < viewDataArray.length; i++) {
const [path] = viewDataArray[i].split(" ");
if (path) {
if (pathViewMap.has(path)) {
pathViewMap.set(path, pathViewMap.get(path) + 1);
} else {
pathViewMap.set(path, 1);
}
}
}
return pathViewMap;
};
对于上下文,输入是来自 paths/ips
列表的日志文件的字符串
编辑 2:
感谢 Peter Seliger,我已经能够想出我自己的解决方案:
const viewDataArray = viewData.split("\n").filter((item) => item);
const arr: { path: string; ip: string }[] = viewDataArray.map(
(line: string) => {
const [path, ip] = line.split(" ");
if (path && ip) {
return { path, ip };
}
}
);
const paths: string[] = Array.from(new Set(arr.map((obj) => obj.path)));
const uniqueViewsMap: Map<string, number> = new Map();
for (let i = 0; i < paths.length; i++) {
const path = paths[i];
const ips = Array.from(
new Set(arr.filter((obj) => obj.path === path).map((obj) => obj.ip))
);
uniqueViewsMap.set(path, ips.length);
}
console.log("==uniqueViewsMap==", uniqueViewsMap);
const sampleData = [
{ path: '/index', ip: '123.456.789' },
{ path: '/index/x', ip: '123.456.789' },
{ path: '/index/', ip: '123.456.78' },
{ path: '/index/y', ip: '123.456.789' },
{ path: '/index/', ip: '123.456.89' },
{ path: 'index/', ip: '123.456.9' },
{ path: 'index', ip: '123.456.8' },
{ path: '/index/', ip: '123.456.78' },
{ path: '/index/x/', ip: '123.456.78' },
{ path: 'index/x/', ip: '123.456.7' },
{ path: 'index/x', ip: '123.456.6' },
];
console.log(
sampleData
.reduce((result, { path, ip }, idx, arr) => {
// sanitize/unify any path value
path = path.replace(/^\/+/, '').replace(/\/+$/, '');
// access and/or create a path specific
// set and add the `ip` value to it.
(result[path] ??= new Set).add(ip);
// within the last iteration step
// transform the aggregated object
// into the final result with the
// path specific unique ip count.
if (idx === arr.length - 1) {
result = Object
.entries(result)
.reduce((obj, [path, set]) =>
Object.assign(obj, {
[path]: set.size
}), {}
);
}
return result;
}, {})
);
我有一个包含两个值的对象数组:{path: '/index', ip: '123.456.789'}
有些路径是相同的,IP 也是如此。一些重复,一些独特的组合。
对于每个唯一路径,我想要附加到该路径的不同 ip 的数量。
因此,例如,可能有 15 个对象 path: '/index'
,但该路径只有 4 个唯一的 ip。
简单来说,我想查找特定网站页面的独立访问者数量。
希望这是有道理的,非常感谢
编辑:
到目前为止,这是我生成非唯一视图的方法:
export const generateViews = (viewData: string): Map<string, number> => {
const pathViewMap: Map<string, number> = new Map();
const viewDataArray = viewData.split("\n");
for (let i = 0; i < viewDataArray.length; i++) {
const [path] = viewDataArray[i].split(" ");
if (path) {
if (pathViewMap.has(path)) {
pathViewMap.set(path, pathViewMap.get(path) + 1);
} else {
pathViewMap.set(path, 1);
}
}
}
return pathViewMap;
};
对于上下文,输入是来自 paths/ips
列表的日志文件的字符串编辑 2:
感谢 Peter Seliger,我已经能够想出我自己的解决方案:
const viewDataArray = viewData.split("\n").filter((item) => item);
const arr: { path: string; ip: string }[] = viewDataArray.map(
(line: string) => {
const [path, ip] = line.split(" ");
if (path && ip) {
return { path, ip };
}
}
);
const paths: string[] = Array.from(new Set(arr.map((obj) => obj.path)));
const uniqueViewsMap: Map<string, number> = new Map();
for (let i = 0; i < paths.length; i++) {
const path = paths[i];
const ips = Array.from(
new Set(arr.filter((obj) => obj.path === path).map((obj) => obj.ip))
);
uniqueViewsMap.set(path, ips.length);
}
console.log("==uniqueViewsMap==", uniqueViewsMap);
const sampleData = [
{ path: '/index', ip: '123.456.789' },
{ path: '/index/x', ip: '123.456.789' },
{ path: '/index/', ip: '123.456.78' },
{ path: '/index/y', ip: '123.456.789' },
{ path: '/index/', ip: '123.456.89' },
{ path: 'index/', ip: '123.456.9' },
{ path: 'index', ip: '123.456.8' },
{ path: '/index/', ip: '123.456.78' },
{ path: '/index/x/', ip: '123.456.78' },
{ path: 'index/x/', ip: '123.456.7' },
{ path: 'index/x', ip: '123.456.6' },
];
console.log(
sampleData
.reduce((result, { path, ip }, idx, arr) => {
// sanitize/unify any path value
path = path.replace(/^\/+/, '').replace(/\/+$/, '');
// access and/or create a path specific
// set and add the `ip` value to it.
(result[path] ??= new Set).add(ip);
// within the last iteration step
// transform the aggregated object
// into the final result with the
// path specific unique ip count.
if (idx === arr.length - 1) {
result = Object
.entries(result)
.reduce((obj, [path, set]) =>
Object.assign(obj, {
[path]: set.size
}), {}
);
}
return result;
}, {})
);