Home > Enterprise >  Create new array from existing array with unique joined values from existing array
Create new array from existing array with unique joined values from existing array

Time:08-12

Does anyone know how I can create a new array from existing array with unique joined values from existing array?

const originalArray = [
  [
    { value: 'red', id: 99 },
    { value: 'blue', id: 100 },
  ],
  [
    { value: 'small', id: 101 },
    { value: 'medium', id: 102 },
  ],
  [
    { value: 'modern', id: 103 },
    { value: 'classic', id: 104 },
  ],
];
//
//
const newArrayBasedOnOriginalArray = [
  { value: 'red/small/modern' },
  { value: 'red/small/classic' },
  { value: 'red/medium/modern' },
  { value: 'red/medium/classic' },
  { value: 'blue/small/modern' },
  { value: 'blue/small/classic' },
  { value: 'blue/medium/modern' },
  { value: 'blue/medium/classic' },
];

I calculated that the length of the new array should always be as following:

// length of new array
const lengthOfNewArray = originalArray
  .map((value) => {
    return value.length;
  })
  .reduce((current, old) => {
    return current * old;
  });
//
//
console.log('length of new array:', lengthOfNewArray); // 8

CodePudding user response:

You can do it recursively

const originalArray = [
  [
    { value: 'red', id: 99 },
    { value: 'blue', id: 100 },
  ],
  [
    { value: 'small', id: 101 },
    { value: 'medium', id: 102 },
  ],
  [
    { value: 'modern', id: 103 },
    { value: 'classic', id: 104 },
  ],
];

const getPossibleCombination = (currentValue, arraysRemaining) => {
  if(arraysRemaining.length === 0) return currentValue

  const values = []
  
  const firstArray = arraysRemaining[0]
  
  firstArray.forEach(({value}) => {
    values.push(getPossibleCombination(`${currentValue}/${value}`, arraysRemaining.slice(1, arraysRemaining.length)))
  })
  
  return values.flat()
}

const values = getPossibleCombination('', originalArray)
console.log(values)

CodePudding user response:

In this case, you do not necessarily need recursion. Array.reduce() greatly does the job:

const originalArray = [
  [
    { value: 'red', id: 99 },
    { value: 'blue', id: 100 },
  ],
  [
    { value: 'small', id: 101 },
    { value: 'medium', id: 102 },
  ],
  [
    { value: 'modern', id: 103 },
    { value: 'classic', id: 104 },
  ],
];

const newArray = originalArray
  .map(elem => elem.map(({value}) => value))
  .reduce((acc, cur) => acc.flatMap(seq => cur.map(part => `${seq}/${part}`)))
  .map(elem => ({value: elem}))

console.log(newArray)

Aside from the initial and final map(), used to simplify the input objects, what I am doing is continuously combining the accumulator with the next sub-array.

For each object in the sub-array I duplicate every object in the accumulator, using the nested map(). flatMap() is used to keep the accumulator flat, with a simple map() the accumulator depth would increase every time we visit a new sub-array.

CodePudding user response:

First of all if values in each of your arrays is unique then the concatenated values will be unique as well. After you make sure values are unique you can use this code to create combinations of strings:

const newArrayBasedOnOriginalArray = originalArray.reduce(
  (acc, el) =>
    el.flatMap(({ value }) =>
      acc.length ? acc.map((str) => str   "/"   value) : value
    ),
  []
).map(value=>({value});
  • Related