0

Say I have an array:

arr = [25, 25, 25, 20, 15, 10, 10, 5];

and I want to count up the number of duplicates (ie. three 25s and 2 10s) and make a new array that becomes:

newArr = ['25 * 3', 20, 15, '10 * 2', 5];

How should I go about doing this? Thanks!

4
  • Use reduce or a for loop? Commented Aug 12, 2021 at 16:34
  • 1
    What have you tried so far? Commented Aug 12, 2021 at 16:35
  • I think even though he use reduce, he wont be getting the count of the repeated items, right? Commented Aug 12, 2021 at 16:36
  • 1
    This one has been answered here: stackoverflow.com/questions/5667888/… Commented Aug 12, 2021 at 16:52

3 Answers 3

2

It can be solved using Set and filter

let arr = [25, 25, 25, 20, 15, 10, 10, 5];

const newArr = [...new Set(arr)].map((x) => {
    const count = arr.filter(y => y == x).length
    return count > 1 ? x + " * " + count: x;
})

console.log(newArr) //  ["25 * 3", 20, 15, "10 * 2", 5]

or if you want the numeric value you can do that

let arr = [25, 25, 25, 20, 15, 10, 10, 5];
    const newArr = [...new Set(arr)].map((x) => arr.filter(y => y == x).length * x)
    console.log(newArr) // [75, 20, 15, 20, 5]

Sign up to request clarification or add additional context in comments.

Comments

0

You can use a Array#forEach loop to iterate through each item of the array, keeping track of how many times each item has been seen before.

Demo:

let arr = [25, 25, 25, 20, 15, 10, 10, 5];

let result = [], seenBefore = [];

arr.forEach((item) => {
  let seen = seenBefore.indexOf(item);
  if (seen !== -1) return result[seen].count++;
  result.push({ name: item, count: 1 });
  seenBefore.push(item);
});

result = result.map(({ name, count }) =>
  count > 1 ? `${name} * ${count}` : name
);

console.log(result);

The same technique but smaller using Array#reduce:

let arr = [25, 25, 25, 20, 15, 10, 10, 5];

let result = arr
  .reduce(
    (acc, item) => {
      acc[1].indexOf(item) !== -1 ? acc[0][acc[1].indexOf(item)].count++ : (acc[0].push({ name: item, count: 1 }), acc[1].push(item));
      return acc;
    },
    [[], []]
  )[0]
  .map(({ name, count }) => (count > 1 ? `${name} * ${count}` : name));

console.log(result);

Comments

0

You could use reduce and check if the current element in the iteration is equal to the previous element and then also what is the type of last element added to the accumulator.

const arr = [25, 25, 25, 20, 15, 10, 10, 5];
const result = arr.reduce((r, e, i, arr) => {
  if (i && e === arr[i - 1]) {
    if (typeof r[r.length - 1] === 'number') {
      r[r.length - 1] = `${e} * 2`;
    } else {
      const [key, value] = r[r.length - 1].split(' * ')
      r[r.length - 1] = `${key} * ${+value + 1}`
    }
  } else {
    r.push(e)
  }

  return r;
}, [])

console.log(result)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.