D3.js v5 объединение динамических массивов

#javascript #d3.js

#javascript #d3.js

Вопрос:

Для этой конкретной задачи я не могу проанализировать данные. Поэтому мне нужно жестко запрограммировать некоторые данные в желаемом формате:

 var data = ["1Equity","2Equity","3Equity","4Balanced","5Balanced","6MMF","7MMF","8MMF","9MMF","10MMF"];
 

По сути, это массив с многочисленными вхождениями нескольких разных строк; фактический массив будет намного длиннее, и поэтому я ищу устройство для экономии труда.

Я пробовал:

 d3.range(3).map(function(v) { return v "equity"}).push(d3.range(2).map(function(v) { return v "balanced"})).push(d3.range(5).map(function(v) { return v "mmf"}))
 

Однако это вернуло:

Неперехваченный (в обещании) d3.range(…).map(…).push(…).push не является функцией

Вопрос

Как я могу объединить массивы с элементами, сопоставленными нескольким разным строкам (вхождение строки на основе моего описания / настраивается пользователем) в одной строке?

Ответ №1:

Array.prototype.push возвращает новую длину массива. Поэтому вы не можете связать его таким образом (вы вызываете push число, а не массив).

То, что вы хотите, можно легко настроить с помощью reduce :

 const keys = [
  ["Equity", 3],
  ["Balanced", 2],
  ["MMF", 5]
];

const data = keys.reduce((a, c) => a.concat(d3.range(c[1]).map((_, j) => (a.length   (j   1))   c[0])), []);

console.log(data) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> 

Однако, если вы хотите сохранить эту свою цепочку, используйте concat вместо push (как в самом названии вашего вопроса), но тогда у вас возникнут проблемы с индексами:

 const data = d3.range(3).map(function(v) { return v "equity"}).concat(d3.range(2).map(function(v) { return v "balanced"})).concat(d3.range(5).map(function(v) { return v "mmf"}));

console.log(data) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> 

Комментарии:

1. Справедливо, ты меня опередил. Снова 😉 Возможно, вам будет интересно ознакомиться с моим ироничным решением на основе D3: jsfiddle.net/a3mn2v9w Я имею в виду, он сам напросился на это…

Ответ №2:

Ошибка, которую вы наблюдали, вызвана .push() возвратом новой длины массива, а не экземпляра массива, что препятствует цепочке методов.

На мой взгляд, ваша задача может быть легко выполнена с помощью Vanilla JS без необходимости использования D3 вообще:

 const structure = [["Equity", 3], ["Balanced", 2], ["MMF", 5]];

let i = 1;
const data = [].concat(                       // 4. Concatenate all sub-arrays
  structure.map(                              // 1. Iterate structure
    ([k, n]) => new Array(n).fill(undefined)  // 2. Create sub-array of length n for key k
      .map(_ => `${i  }${k}`)                 // 3. Map each item to desired string value
  )
).flat();                                     // 5. Flatten to 1-dimensional array

console.log(data);