使用对象数组,如:
const data = [
{count: 400, value: "Car Wash Drops"},
{count: 48, value: "Personal/Seeding"},
{count: 48, value: "Personal/Seeding"},
];我想要map到一个具有重复值的附加标识符的数组:
const expected = [
["Car Wash Drops", 400],
["Personal/Seeding (1)", 48],
["Personal/Seeding (2)", 48],
];到目前为止,我有一个map函数来相应地映射值,但我不知道如何只为重复的值追加标识符。
data.map(d => [`${d.value}`, d.count]);在以下方面的成果:
[
["Car Wash Drops", 400],
["Personal/Seeding", 48],
["Personal/Seeding", 48],
]我也使用了索引,但它在每个值上都添加了索引:
data.map((d, i) => [`${d.value} ${i}`, d.count]);在以下方面的成果:
[
["Car Wash Drops (0)", 400],
["Personal/Seeding (1)", 48],
["Personal/Seeding (2)", 48],
]发布于 2019-01-16 17:08:40
使用您的方法,您可以在映射中使用filter()来检查原始数组中有多少元素与当前分析的元素具有相同的值,使用此条件,您可以选择返回什么作为新值:
const data = [
{count: 400, value: "Car Wash Drops"},
{count: 48, value: "Personal/Seeding"},
{count: 48, value: "Personal/Seeding"},
];
let res = data.map((x, idx) =>
{
if (data.filter(y => y.value === x.value).length > 1)
return [`${x.value} (${idx})`, x.count];
else
return [`${x.value}`, x.count];
});
console.log(res);
如果我们使用some()而不是filter(),可以提高以前方法的性能,如下所示:
const data = [
{count: 400, value: "Car Wash Drops"},
{count: 48, value: "Personal/Seeding"},
{count: 48, value: "Personal/Seeding"},
{count: 300, value: "Operators/Management"},
{count: 48, value: "Personal/Seeding"}
];
let res = data.map((x, idx) =>
{
if (data.some((y, j) => y.value === x.value && idx !== j))
return [`${x.value} (${idx})`, x.count];
else
return [`${x.value}`, x.count];
});
console.log(res);
如果我们以前创建了一个地图,它的计数器是元素出现在原始数组中的时间,那么它可能会得到更大的改进。如下所示:
const data = [
{count: 400, value: "Car Wash Drops"},
{count: 48, value: "Personal/Seeding"},
{count: 48, value: "Personal/Seeding"},
{count: 300, value: "Operators/Management"},
{count: 48, value: "Personal/Seeding"}
];
let counters = data.reduce((res, {value}) =>
{
res.set(value, res.has(value) ? res.get(value) + 1 : 1);
return res;
}, new Map());
let res = data.map((x, idx) =>
{
return [
`${x.value}` + (counters.get(x.value) > 1 ? `(${idx})` : ""),
x.count
];
});
console.log(res);
发布于 2019-01-21 05:07:32
答案已经给出了,尽管我完全尊重答案的作者,但我认为答案可能会有一些改进,无论是在语法上还是在性能上:
reduce,但是如果源相对较小,我总是更喜欢reduce (data.length<1000)。尝试使用POF (普通旧的for :),因为它是最快的选项。我将为这个问题提供我的解决方案(它将运行O(n)并在最坏的情况下为键值对使用额外的O(n)空间,它会对源进行两次传递,因此,第二次传递需要将1放在我们第一次遇到它时错过的地方):
let data = [
{count: 400, value: "Car Wash Drops"},
{count: 48, value: "Personal/Seeding"},
{count: 48, value: "Personal/Seeding"},
{count: 300, value: "Operators/Management"},
{count: 48, value: "Personal/Seeding"}
];
const map = {};
for (let i=0;i<data.length;i+=1) {
map[ data[i].value ] = map[ data[i].value ]+1 || 0;
data[i].value = map[data[i].value]?data[i].value+` (${map[data[i].value]+1})`:data[i].value;
}
for (let i=0;i<data.length;i+=1) {
data[i].value = map[data[i].value]?data[i].value+` (1)`:data[i].value;
}
console.log(data.map(o=>[o.value,o.count]));
或使用ES6 of运算符[链接至.]更简洁的版本
let data = [
{count: 400, value: "Car Wash Drops"},
{count: 48, value: "Personal/Seeding"},
{count: 48, value: "Personal/Seeding"},
{count: 300, value: "Operators/Management"},
{count: 48, value: "Personal/Seeding"}
];
const map = {};
for (let d of data) {
map[d.value] = map[d.value]+1 || 0;
d.value = map[d.value]?d.value+` (${map[d.value]+1})`:d.value;
}
for (let d of data) {
d.value = map[d.value]?d.value+` (1)`:d.value;
}
console.log(data.map(o=>[o.value,o.count]));
发布于 2019-01-16 17:06:06
您可以维护一个映射,从您看到的值到您所见过的值的数量。然后,根据是否存在重复,就可以更容易地得到正确的数字:
const data = [
{count: 400, value: "Car Wash Drops"},
{count: 48, value: "Personal/Seeding"},
{count: 48, value: "Personal/Seeding"},
];
let valueCounts = data.reduce((a, c) => {
a[c.value] = a[c.value] || {current: 1, total: 0};
a[c.value].total += 1;
return a;
}, {});
const expected = data.map(({count, value}) => {
if (valueCounts[value].total === 1) return [value, count];
return [`${value} (${valueCounts[value].current++})`, count];
});
console.log(expected);
https://stackoverflow.com/questions/54221759
复制相似问题