Mam wyraźnie trudny problem manipulacji danych JavaScript, z którym walczę. Mam następującą tablicę danych:

var myArray = [8, 13, 11, 17, 5, 13, 13];

I chciałbym mapować tę tablicę w tablicę o równej długości, gdzie każda wartość w nowej tablicy jest równa różnicy między poprzednią wartością tablicy w tym miejscu, a następna najniższa wartość w poprzedniej tablicy . Jest to słowo, ale na przykład chcę, aby wyjście było:

var newArray = [3, 2, 3, 4, 5, 0, 0]; 

3 W pierwszym elemencie znajduje się (8 - 5), gdzie 8 jest poprzednią wartością tablicy w pierwszej gniazda, a 5 jest następną najniższą wartością w poprzedniej tablicy. 2 W drugim elemencie jest (13 - 11), ... itd.

Nie dążę szczególnie dbając o sposobów obsługi (na przykład 2 wartości 13 w oryginalnej tablicy), tak długo, jak dokładnie jedna instancja 13 zostanie zastąpiona (13 - następna najniższa wartość), a wszystkimi innymi instancjami z 13 są zastępowane zero (13 - 13 zasadniczo).

Dzięki!

3
Canovice 4 czerwiec 2018, 22:52

4 odpowiedzi

Najlepsza odpowiedź

Korzystanie z redukcji () w mapie () i sprawdzanie numeru jest pierwszej instancji lub nie stosując indexof ()

var arr = [8, 13, 11, 17, 5, 13, 13];

var res = arr.map((n, i) => {
  if (i !== arr.indexOf(n)) return 0;
  return n - arr.reduce((a, c) => c < n && c > a ? c : a, 0);
})

console.log(JSON.stringify(res))/// [3, 2, 3, 4, 5, 0, 0]

Alternatywne podejście, które tworzy malejącą sortowaną tablicę Uniques, a następnie szuka liczby w następnym indeksie w ramach tej tablicy

var arr = [8, 13, 11, 17, 5, 13, 13];
var sortedUniques  = [...new Set(arr)].sort((a,b) => b-a);

var res = arr.map((n, i) => {
  if (i !== arr.indexOf(n)) return 0;
  var sortedIdx = sortedUniques.indexOf(n);
  return n - ( sortedUniques[sortedIdx+1] || 0 );
})

console.log(JSON.stringify(res))/// [3, 2, 3, 4, 5, 0, 0]
3
charlietfl 4 czerwiec 2018, 20:57

Duże dzięki @CharlietFl, który pomógł mi zrozumieć część duplikatów :) W ogóle wymyśliłem niemal identyczne rozwiązanie, zapisz do używania Array.filter i Math.max zamiast minimalizowania tego do jednego {x1}} {X2}} oświadczenie.

let myArray = [8, 13, 11, 17, 5, 13, 13],
    cmpArray = myArray.concat([0]);

console.log(
  myArray.map((value, index) => {
    if(index !== myArray.indexOf(value)) return 0;
    return value - Math.max(...cmpArray.filter(number => number < value));
  })
);
1
wiesion 4 czerwiec 2018, 21:15

Możesz odebrać następne wartości w tablicy i wszystkie tablicę w obiekcie i wyskoczyć wartości, aż wszystkie wartości zostaną pobrane.

var array = [8, 13, 11, 17, 5, 13, 13],
    temp = array
        .slice()
        .sort((a, b) => b - a)
        .reduce(
            (r, v, i, a) => ((r[v] = r[v] || []).push(v - (a[i + 1] || 0)), r),
            Object.create(null)
        ),
    result = array.map(v => temp[v].pop());

console.log(result);
1
Nina Scholz 5 czerwiec 2018, 06:04

Coś wzdłuż tych linii zbliża się do mnie.

let newArray = [];
myArray.forEach(function(d){
  let temp = myArray.filter(val => val < d)
  let maxRemVal = d3.max(temp)
  maxRemVal = isNaN(maxRemVal) ? 0 : maxRemVal;
  newArray.push(d - maxRemVal)
});
0
Canovice 4 czerwiec 2018, 20:12