0

I'm trying to combine arrays of string with unique combinations, like 'Mark|Tom' but without 'Tom|Mark'

I have written this code:

let arr = ['Tom', 'Danny', 'Mark']
let sets = []

for (let i = 0; i < arr.length; i++) {
  let others = arr.filter(name => name != arr[i])
  others.forEach((other) => {

    let newel = arr[i] + '|' + other
    let test = newel.split('|')
    if (sets.includes(test[1] + '|' + test[0]) || sets.includes(newel)) return

    sets.push(newel)
  })

}

console.log(sets)

This is iterating through every array element and then creating another array of other elements from basic array and then iterating through them (again iteration), creating a combination, checking if there is reversed combination of our elements (if this was created in previous loops) and if there is no such combination = push it to target array.

Is there more elegant way to do that task?

5
  • 2
    can you post what is desired output ? also why it should be Mark|Tom not Tom|Mark ? Commented Sep 16, 2019 at 1:16
  • just run code snippet It's irrelevant if it's Mark|Tom or Tom|Mark, it has to be unique combination Commented Sep 16, 2019 at 1:18
  • Output your code showing is doesn't matches with logic, so it will be better to desired result, You want to Tony|Dany|Mark also to be in output ? Commented Sep 16, 2019 at 1:23
  • Sure! The next step is to match treble combination Commented Sep 16, 2019 at 1:24
  • please update your post with desired result Commented Sep 16, 2019 at 1:25

4 Answers 4

3

what about this one:

const arr = ['Tom', 'Danny', 'Mark'];
const sets = [];

for (let i = 0; i < arr.length; i++) {
  for (let j = i + 1; j < arr.length; j++) {
    sets.push(arr[i] + '|' + arr[j]);
  }
}

console.log(sets);

Also you can make arr unique before start the calculate:

const arr = [...new Set(['Tom', 'Danny', 'Mark', 'Tom'])]; // ['Tom', 'Danny', 'Mark']
Sign up to request clarification or add additional context in comments.

3 Comments

You can create a running snippet on SO mate, how to create a running snippet
@CodeManiac Ahhh thank you very much! I was looking for it :)
Always welcome, anyways good answer and probably the most efficient one +1
2

I would make your array a set so it will remove all duplicates initially like so:

new Set(['Tom', 'Danny', 'Mark']);

Now, you can pair the ith element with all elements up to the nth element using .flatMap and .reduce like so:

const name_arr = Array.from(new Set(['Tom', 'Danny', 'Mark']));
const res = name_arr.flatMap(
  (name, i) => name_arr.slice(i+1).reduce((a, n) => [...a, name+'|'+n],[])
);

console.log(res);

Comments

1

You can create a Set of passed array, loop through the array, for each index get the array after that index and loop thorough this other array and build combinations

let arr = ['Tom', 'Danny', 'Mark']

const uniqueCombo = (arr) => {
  let newSet = [...new Set(arr)]
  return newSet.reduce((op, inp, index) => {
    newSet.slice(index + 1,).forEach(v => {
      op.push(inp + '|' + v)
    })
    return op
  },[])
}

console.log(uniqueCombo(arr))
console.log(uniqueCombo(['A', 'B', 'A', 'C', 'D']))
console.log(uniqueCombo(['A', 'B', 'A', 'C']))

Comments

0

Try this one. This approach filters out the index which has been previously used to push item to array.

const arr = ['Tom', 'Danny', 'Mark'];

const comb = [];
for (let i = 0; i < arr.length; i++) {
  for (j = i + 1; j < arr.length; j++) {
    comb.push(arr[i] + '|' + arr[j]);
  }
}
console.log(comb);

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.