Mam dwie tablice:

const sizes = ['large', 'medium']
const colors = ['blue', 'red', 'orange']

Muszę utworzyć ostateczną tablicę, która łączy tablicę ze wszystkimi możliwymi wartościami takimi jak:

const final = ['blue large', 'red large', 'orange large', 'blue medium', 'red medium', 'orange medium']

Oba sizes i colors mogą być puste.

Wolę to zrobić za pomocą lodash i próbowałem foreach pętli jak:

sizes.forEach((size) => {
  colors.forEach((color) => {
    actualVariants.push(`${size} ${color}`)
  })
})

colors.forEach((size) => {
  sizes.forEach((color) => {
    actualVariants.push(`${color} ${size}`)
  })
})

Teraz, to jednak zadziałało: zawiera duplikaty i chcę się upewnić, że robię to w najbardziej skuteczny sposób.

To również nie działa, gdy tablice są puste.

-1
randomKek 27 czerwiec 2017, 13:41

3 odpowiedzi

Najlepsza odpowiedź

Wystarczy usunąć pierwszy blok:

Przykład: https://jsbin.com/qovojacuci/edit19js,console

const sizes = ['large', 'medium']
const colors = ['blue', 'red', 'orange']

let actualVariants = []

colors.forEach((size) => {
  sizes.forEach((color) => {
    actualVariants.push(`${color} ${size}`)
  });
});

console.log(actualVariants);

Jeśli chcesz, aby twoja tablica posortowała jak you final stała, zmień kolejność pętli:

const sizes = ['large', 'medium']
const colors = ['blue', 'red', 'orange']

let actualVariants = []

sizes.forEach((size) => {
  colors.forEach((color) => {
    actualVariants.push(`${color} ${size}`)
  });
});

console.log(actualVariants);
2
user93 27 czerwiec 2017, 11:54

Zdefiniowałem metodę ogólnego zastosowania combine, które może łączyć dwie tablice do jednego.

Metoda zawsze będzie pętli arr1.length * arr2.length razy, aby móc wyprodukować wszystkie ważne wyniki. Tak więc, dla ['a', 'b', 'c'] i [1, 2] otrzymasz 3 x 2 = 6 łączyć połączenia i macierz o długości 6.

Korzyść z napisania go jako funkcji, która zajmuje dwie tablice i zwraca jeden, a obsługuje puste tablice, jest to, że można użyć go wewnątrz reduce, aby połączyć dowolną liczbę tablic !

// `combiner` is a function that combines an element from `xs`
// and one from `ys` in to one value
const combine = combiner => (xs, ys) => {
  if (!xs || !xs.length) return ys;
  if (!ys || !ys.length) return xs;
  
  // Note, this can still be done using two forEach loops
  // in some cases, `concat` might be too slow...
  return xs.reduce(
    (acc, x) => acc.concat(ys.map(combiner(x))),
    []
  );
}
  
// Example use:

// Make different combiners:
const combineWithSpace = combine(x => y => `${x} ${y}`);
const combineWithDot = combine(x => y => `${x}.${y}`);

const prefix = ["a", "b", "c"];
const suffix = [1, 2];

// Now  you can do:
log("Prefix Suffix:", combineWithSpace(prefix, suffix));

// Support for empty arrays:
log("One empty array:", combineWithSpace(prefix, []));

// But you can also use it as a reducer:
log("Custom:", 
  [prefix, suffix, ["i", "ii", "iii"]].reduce(combineWithDot)
);


function log(label, arr) { console.log(label, JSON.stringify(arr)) };
0
user3297291 27 czerwiec 2017, 12:03

I rozwiązanie za pośrednictwem pętli:

const sizes = ['large', 'medium'];
const colors = ['blue', 'red', 'orange'];

var final=new Array();

for(var i=0;i<sizes.length;i++){
  for(var z=0;z<colors.length;z++){
    final.push(colors[z]+' '+sizes[i]);
  }
}
console.log(final);
0
liontass 27 czerwiec 2017, 11:00