首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用标识符将对象数组映射到数组以获得重复的值?

如何使用标识符将对象数组映射到数组以获得重复的值?
EN

Stack Overflow用户
提问于 2019-01-16 16:51:59
回答 4查看 965关注 0票数 4

使用对象数组,如:

代码语言:javascript
复制
const data = [
  {count: 400, value: "Car Wash Drops"},
  {count: 48, value: "Personal/Seeding"},
  {count: 48, value: "Personal/Seeding"},
];

我想要map到一个具有重复值的附加标识符的数组:

代码语言:javascript
复制
const expected = [
  ["Car Wash Drops", 400],
  ["Personal/Seeding (1)", 48],
  ["Personal/Seeding (2)", 48],
];

到目前为止,我有一个map函数来相应地映射值,但我不知道如何只为重复的值追加标识符。

代码语言:javascript
复制
data.map(d => [`${d.value}`, d.count]);

在以下方面的成果:

代码语言:javascript
复制
[
  ["Car Wash Drops", 400],
  ["Personal/Seeding", 48],
  ["Personal/Seeding", 48],
]

我也使用了索引,但它在每个值上都添加了索引:

代码语言:javascript
复制
data.map((d, i) => [`${d.value} ${i}`, d.count]);

在以下方面的成果:

代码语言:javascript
复制
[
  ["Car Wash Drops (0)", 400],
  ["Personal/Seeding (1)", 48],
  ["Personal/Seeding (2)", 48],
]
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-01-16 17:08:40

使用您的方法,您可以在映射中使用filter()来检查原始数组中有多少元素与当前分析的元素具有相同的值,使用此条件,您可以选择返回什么作为新值:

代码语言:javascript
复制
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(),可以提高以前方法的性能,如下所示:

代码语言:javascript
复制
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);

如果我们以前创建了一个地图,它的计数器是元素出现在原始数组中的时间,那么它可能会得到更大的改进。如下所示:

代码语言:javascript
复制
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);

票数 3
EN

Stack Overflow用户

发布于 2019-01-21 05:07:32

答案已经给出了,尽管我完全尊重答案的作者,但我认为答案可能会有一些改进,无论是在语法上还是在性能上:

  1. 如果源非常大,则应该避免使用reduce,但是如果源相对较小,我总是更喜欢reduce (data.length<1000)。尝试使用POF (普通旧的for :),因为它是最快的选项。
  2. 当我们处理键值对时,ES6映射是一个很好的助手,但如果可能的话,我更喜欢po(普通的旧对象:),它将使我们的代码更加美观。

我将为这个问题提供我的解决方案(它将运行O(n)并在最坏的情况下为键值对使用额外的O(n)空间,它会对源进行两次传递,因此,第二次传递需要将1放在我们第一次遇到它时错过的地方):

代码语言:javascript
复制
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运算符[链接至.]更简洁的版本

代码语言:javascript
复制
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]));

票数 1
EN

Stack Overflow用户

发布于 2019-01-16 17:06:06

您可以维护一个映射,从您看到的值到您所见过的值的数量。然后,根据是否存在重复,就可以更容易地得到正确的数字:

代码语言:javascript
复制
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);

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54221759

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档