Удаление дубликатов объектов в массиве объектов с сохранением уникальных строковых значений - PullRequest
0 голосов
/ 25 октября 2018

Пожалуйста, потерпите меня, я начинающий разработчик javascript с проблемой сортировки, которую я не могу обернуть.

Я получаю массив объектов (ответ JSON) через API, например:

var arr = [
    {
        "year": "2011",
        "activity": "bowling"
    },
    {
        "year": "2009",
        "activity": "shopping",
    },
    {
        "year": "2011",
        "activity": "cooking"
    },
    {
        "year": "2006",
        "activity": "singing"
    }
]

У меня есть функция, которая удаляет все дубликаты лет (как и предполагалось), ноЯ хочу взять значение «активность» дубликата объекта и добавить его к значению активности того же года, которое осталось после удаления дубликатов

Моя функция удаления дубликата выглядит следующим образом

var new_arr = new_arr.reduce((unique, o) => {
  if(!unique.some(obj => obj.year === o.year)) {
    unique.push(o);
  }
  return unique;
},[]);

что оставляет меня с этим

var arr = [
    {
        "year": "2011",
        "activity": "bowling"
    },
    {
        "year": "2009",
        "activity": "shopping",
    },
    {
        "year": "2006",
        "activity": "singing"
    }
]

Чего я хочу достичь:

var arr = [
    {
        "year": "2011",
        "activity": "bowling, cooking"
    },
    {
        "year": "2009",
        "activity": "shopping",
    },
    {
        "year": "2006",
        "activity": "singing"
    }
]

JSFiddle: https://jsfiddle.net/4s1uaex0/2/

Я чувствую, что япочти там, но я не знаю, с чего начать.Кто-нибудь может указать мне правильное направление с помощью руководства или примера?Помощь будет принята с благодарностью!Спасибо

Ответы [ 4 ]

0 голосов
/ 15 января 2019

const inputArr = [
    {
        "year": "2011",
        "activity": "bowling"
    },
    {
        "year": "2009",
        "activity": "shopping",
    },
    {
        "year": "2011",
        "activity": "cooking"
    },
    {
        "year": "2006",
        "activity": "singing"
    }
];

const outputArr = inputArr.sort((objA, objB) => Number(objA.year) - Number(objB.year))
    .reduce((accu, obj) => {
        const len = accu.length;
        if(len == 0 || accu[len-1].year !== obj.year) {
            accu.push(obj);
        } else {
            accu[len-1].activity += ', ' + obj.activity;
        }
        return accu;
    }, []);

console.log(outputArr);
0 голосов
/ 25 октября 2018

Вместо проверки, существует ли уже год в вашем аккумуляторе: проверьте и измените.

const arr = [{
    year: '2011',
    activity: 'bowling',
  },
  {
    year: '2009',
    activity: 'shopping',
  },
  {
    year: '2011',
    activity: 'cooking',
  },
  {
    year: '2011',
    activity: 'cooking',
  },
  {
    year: '2006',
    activity: 'singing',
  },
];

const new_arr = arr.reduce((tmp, x) => {
  // Already exist
  const exist = tmp.find(y => y.year === x.year);

  if (exist) {
    // Only add not existing activities to avoid duplicates
    if (exist.activity.indexOf(x.activity) === -1) {
      exist.activity = `${exist.activity}, ${x.activity}`;
    }

    return tmp;
  }

  tmp.push(x);

  return tmp;
}, []);

console.log(new_arr);
0 голосов
/ 25 октября 2018

Вы можете просто использовать для цикла

    var mem = {};
    for(var i = 0; i < arr.length; i++) {
        var currentItem = arr[i];
        var year = currentItem['year'];
        var activity =  currentItem['activity'];
        if(!mem.hasOwnProperty(year)) {
            mem[year] = { 'year' : year, "activity": []};
        }
        mem[year]['activity'].push(activity);
    }

    var final = Object.values(mem);
0 голосов
/ 25 октября 2018

Попробуйте reduce - сначала введите activity в массив в аккумуляторе, а затем присоедините каждое свойство activity через запятую.Вы можете достичь этого с помощью одного reduce, то есть O(N), а some внутри него сделает его O(N^2), что не является необходимым и, вероятно, нежелательным:

var arr = [
    {
        "year": "2011",
        "activity": "bowling"
    },
    {
        "year": "2009",
        "activity": "shopping",
    },
    {
        "year": "2011",
        "activity": "cooking"
    },
    {
        "year": "2006",
        "activity": "singing"
    }
];
const output = Object.values(
  arr.reduce((a, { year, activity }) => {
    if (!a[year]) a[year] = { year, activity: [] };
    a[year].activity.push(activity);
    return a;
  }, {})
);
output.forEach((item) => {
  item.activity = item.activity.join(', ');
});
console.log(output);
...