2

I can check if the objects of an array are also present in another array (and display the duplicates in its own array) with the following code:

var target = ['alfredo', 'john', 'sebas', 'paul', 'lionel', 'sebas2'];
var src = ['paul', 'michael', 'sebas'];

var final = target.filter(function(val) {
  return src.indexOf(val) != -1;
});

console.log(final);

Desired Output:

However, I do not know how to get following output:

final = Array ["paul2", "michael", "sebas3"]

Objects in array final should have the same order as originally in array src but, if the object is also to be found in array target a number (starting from 2) should be attached to this duplicated object. In case the name + number exists, the number has to increase by 1 until the value is not found in target

My try so far:

var final= [];

src.forEach(function(element) {
  if(target.includes(element))
    { newSrc = element+2; final.push(newSrc) } else { final.push(element) }
});

console.log(final);

However, I do not know how to deal with the number + 1 part without recurring to loops in loops etc.

3
  • 2
    Hmmm ... I think the best answer I can give is: change your datastructure. Why not just { michael: 2, john: 1 ... } or at least clearly seperate index and username, such as username#12 ? Commented Jul 25, 2018 at 15:58
  • @Andreas thanks for the feedback. I updated my question to reflect my try so far Commented Jul 25, 2018 at 16:10
  • @JonasW. input comes as it is... I could maybe create a new Array reflection this structure... good idea. Commented Jul 25, 2018 at 16:11

2 Answers 2

2

You could count first and then map the names with the adjusted count.

var target = ['alfredo', 'john', 'sebas', 'paul', 'lionel', 'sebas2'],
    src = ['paul', 'michael', 'sebas'],
    count = target.reduce((c, s) => (k => (c[k] = (c[k] || 0) + 1, c))(s.match(/^\D+/)[0]), Object.create(null)),
    final = src.map(s => s + (count[s] ? count[s] + 1 : ''));

console.log(final);

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

1 Comment

Thanks Nina... this is a new set of functions that I didn't know at all. I was trying to avoid loops in loops and this is exactly perfect. I just need to slowly go through it and try to understand how reduce and map works.
1

An alternative is using the function reduce to group the names and the function some to check for strings str + number. This grouping process creates an object to leverage the fast access using keys.

After that grouping process, get the keys for building the desired output.

var target = ['alfredo', 'john', 'sebas', 'paul', 'lionel', 'sebas2'],
  src = ['paul', 'michael', 'sebas'],
  obj = src.reduce((a, str) => {
    if (target.some(s => str === s))  {
      a[str] = (a[str] || 1) + 1
      while (target.some(s => `${str}${a[str]}` === s)) a[str]++;
    } else a[str] = 0;

    return a;
  }, {}),
  result = Object.keys(obj).map(k => `${k}${obj[k] || '' }`);

console.log(result);
.as-console-wrapper {  max-height: 100% !important;top: 0;}

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.