JavaScript:为对象数组中的每个唯一值创建一个序列
JavaScript: create a sequence for each unique value in array of objects
我有一个对象数组,我想根据每个值创建一个序列。以数组为例:
let starting_data = [
{str: "a"},
{str: "a"},
{str: "b"},
{str: "c"},
{str: "a"},
{str: "c"},
{str: "a"},
{str: "b"}
]
我知道我可以使用 map 和 reduce 找到每个 str
值的唯一编号
let uniques = starting_data.map(function(value) {return value.str;}).reduce((acc, val) => {
acc[val] = acc[val] === undefined ? 1 : acc[val] += 1;
return acc;
}, {})
但我不确定如何利用它最终获得我想要的输出:
let desired_output = [
{str: "a", count: 1},
{str: "a", count: 2},
{str: "b", count: 1},
{str: "c", count: 1},
{str: "a", count: 3},
{str: "c", count: 2},
{str: "a", count: 4},
{str: "b", count: 2}
]
每个唯一值的计数都重新开始,但是 a
转到 4,b
和 c
转到 2。我试着弄乱 arr.sort
如果我需要先这样做,但我不确定如何根据对象内的值进行排序...感谢任何帮助!
可以做一些事情,比如保留一个单独的对象来跟踪计数
let starting_data = [
{str: "a"},
{str: "a"},
{str: "b"},
{str: "c"},
{str: "a"},
{str: "c"},
{str: "a"},
{str: "b"}
]
let counts = {};
let res = starting_data.map(({str}) => {
if(!counts[str])counts[str]=0;
counts[str]+=1
return {str,count:counts[str]}
})
console.log(res)
你提到过你希望它是纯粹的功能性的,所以就在这里。
let starting_data = [
{ str: "a" },
{ str: "a" },
{ str: "b" },
{ str: "c" },
{ str: "a" },
{ str: "c" },
{ str: "a" },
{ str: "b" },
];
const uniqueCount = starting_data
.reduce(
(arr, { str }) => {
const hash = arr[0];
hash[str] ||= 0;
arr.push({ str, count: ++hash[str] });
return arr;
},
[{}]
)
.slice(1);
console.log(uniqueCount);
这会打印:
[
{ str: 'a', count: 1 },
{ str: 'a', count: 2 },
{ str: 'b', count: 1 },
{ str: 'c', count: 1 },
{ str: 'a', count: 3 },
{ str: 'c', count: 2 },
{ str: 'a', count: 4 },
{ str: 'b', count: 2 }
]
工作原理
此解决方案将散列作为 reduce
构建的数组的第一个元素。
- 数组开始于
[{}]
。
- 如果哈希键不存在,则用
0
填充哈希键。
- 使用
str
和 count
将新元素推送到数组。
hash[str]
加1,然后作为值。
数组现在看起来像:
[{ a: 1 }, { str: "a", count: 1 }]
- 我们继续这样做,直到我们遍历每个项目。
[ { a: 2 }, { str: 'a', count: 1 }, { str: 'a', count: 2 } ]
[ { a: 2, b: 1 }, { str: 'a', count: 1 }, { str: 'a', count: 2 }, { str: 'b', count: 1 } ]
// Continues until it finishes
- 最后,我们通过从第一个元素开始对数组进行切片来删除这个初始散列。
希望对您有所帮助。
我有一个对象数组,我想根据每个值创建一个序列。以数组为例:
let starting_data = [
{str: "a"},
{str: "a"},
{str: "b"},
{str: "c"},
{str: "a"},
{str: "c"},
{str: "a"},
{str: "b"}
]
我知道我可以使用 map 和 reduce 找到每个 str
值的唯一编号
let uniques = starting_data.map(function(value) {return value.str;}).reduce((acc, val) => {
acc[val] = acc[val] === undefined ? 1 : acc[val] += 1;
return acc;
}, {})
但我不确定如何利用它最终获得我想要的输出:
let desired_output = [
{str: "a", count: 1},
{str: "a", count: 2},
{str: "b", count: 1},
{str: "c", count: 1},
{str: "a", count: 3},
{str: "c", count: 2},
{str: "a", count: 4},
{str: "b", count: 2}
]
每个唯一值的计数都重新开始,但是 a
转到 4,b
和 c
转到 2。我试着弄乱 arr.sort
如果我需要先这样做,但我不确定如何根据对象内的值进行排序...感谢任何帮助!
可以做一些事情,比如保留一个单独的对象来跟踪计数
let starting_data = [
{str: "a"},
{str: "a"},
{str: "b"},
{str: "c"},
{str: "a"},
{str: "c"},
{str: "a"},
{str: "b"}
]
let counts = {};
let res = starting_data.map(({str}) => {
if(!counts[str])counts[str]=0;
counts[str]+=1
return {str,count:counts[str]}
})
console.log(res)
你提到过你希望它是纯粹的功能性的,所以就在这里。
let starting_data = [
{ str: "a" },
{ str: "a" },
{ str: "b" },
{ str: "c" },
{ str: "a" },
{ str: "c" },
{ str: "a" },
{ str: "b" },
];
const uniqueCount = starting_data
.reduce(
(arr, { str }) => {
const hash = arr[0];
hash[str] ||= 0;
arr.push({ str, count: ++hash[str] });
return arr;
},
[{}]
)
.slice(1);
console.log(uniqueCount);
这会打印:
[
{ str: 'a', count: 1 },
{ str: 'a', count: 2 },
{ str: 'b', count: 1 },
{ str: 'c', count: 1 },
{ str: 'a', count: 3 },
{ str: 'c', count: 2 },
{ str: 'a', count: 4 },
{ str: 'b', count: 2 }
]
工作原理
此解决方案将散列作为 reduce
构建的数组的第一个元素。
- 数组开始于
[{}]
。 - 如果哈希键不存在,则用
0
填充哈希键。 - 使用
str
和count
将新元素推送到数组。 hash[str]
加1,然后作为值。
数组现在看起来像:
[{ a: 1 }, { str: "a", count: 1 }]
- 我们继续这样做,直到我们遍历每个项目。
[ { a: 2 }, { str: 'a', count: 1 }, { str: 'a', count: 2 } ]
[ { a: 2, b: 1 }, { str: 'a', count: 1 }, { str: 'a', count: 2 }, { str: 'b', count: 1 } ]
// Continues until it finishes
- 最后,我们通过从第一个元素开始对数组进行切片来删除这个初始散列。
希望对您有所帮助。