@Morshynska

Работа с массивом и строкой, как вывести такое в консоль?

Есть массив массивов:

const textArray = [
   ["Hello", "world"],
   ["Brad", "came", "to", "dinner", "with", "us"],
   ["He", "loves", "tacos"]
];

Есть набор строк, условия форматирования каждой этой строки - чтобы она не превышала 16 символов и бала заключена символом " * " со всех сторон.

На выходе должно получится что-то вроде:

[
  "******************",
  "*Hello world     *",
  "*    Brad came to*",
  "*  dinner with us*",
  "*He loves tacos  *",
  "******************"
]
  • Вопрос задан
  • 191 просмотр
Решения вопроса 2
0xD34F
@0xD34F Куратор тега JavaScript
const getStrs = (arrs, len) => [
  '*'.repeat(len + 2),
  ...arrs.flatMap(arr => arr
    .reduce((acc, n) => {
      let g = acc[acc.length - 1];
      (g && (g[1] + n.length + !!g[0].length) <= len) || acc.push(g = [ [], 0 ]);
      g[1] += n.length + !!g[0].length;
      g[0].push(n);
      return acc;
    }, [])
    .map((n, i, a) => `*${n[0].join(' ')[a.length > 1 ? 'padStart' : 'padEnd'](len, ' ')}*`)),
  '*'.repeat(len + 2),
];


console.log(getStrs(textArray, 16));
Ответ написан
Комментировать
groog
@groog
Я только учусь
 Если вы хотите поразить публику умением решить данную задачу в одну строку, писать плохой и неподдерживаемый код, который сложно понять, то пригодится это вариант

[
  "*".repeat(18),
  ...textArray
    .map(words => words.join(" "))
    .map(line => {
      const pad = (line.length > 16)?''.padStart:''.padEnd;
      const lines = [];
      let restLine = line;
      while(restLine.length > 16) {
        const spaceIndex = restLine.lastIndexOf(" ", 16);
        lines.push(pad.call(restLine.slice(0, spaceIndex), 16));
        restLine = restLine.slice(spaceIndex + 1);
      }
      lines.push(pad.call(restLine, 16));
      return lines;
    })
    .flat()
    .map(line => "*" + line + "*"),
  "*".repeat(18)
]


Но если вы хотите, чтобы вас поняли и, самое главное, вы поняли, что написали, то лучше делать так:

function formatTextArray(textArray, maxLineLength = 16) {
  const formatedTextArray = [];
  
  textArray
    .forEach(words => {
      const line = words.join(" ");
      
      if(line.length > maxLineLength) {
        splitLine(line)
          .forEach(item => formatedTextArray.push(align(item, false)) );
      } else {
        formatedTextArray.push(align(line));
      }
    }, []);
    
  return addBorders(formatedTextArray);
  
  function align(line = "", isLeft = true) {
    let newLine;
    
    if(isLeft) {
      newLine = line.padEnd(maxLineLength);
    } else {
      newLine = line.padStart(maxLineLength);
    }
    
    return newLine;
  }
  
  function splitLine(line) {
    if(line.length > maxLineLength) {
      const spaceIndex = line.lastIndexOf(" ", maxLineLength);
      const lineStartPart = line.slice(0, spaceIndex);
      const restLine = line.slice(spaceIndex + 1);
      return ([lineStartPart]).concat(splitLine(restLine));
    } else {
      return [line]
    }
  }
  
  function addBorders(formatedTextArray, symbol = "*") {
    const borderedTextArray = [
      symbol.repeat(maxLineLength),
      ...formatedTextArray,
      symbol.repeat(maxLineLength)
    ];

    return borderedTextArray.map(addHorizontalBorders);
    
    function addHorizontalBorders(line) {
      return symbol + line + symbol;
    }
  }
}


А вот интерактивный пример

Ну и задачка со звездочкой, найдите где этот код будет работать не корректно
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
sergiks
@sergiks Куратор тега JavaScript
♬♬
Пройти по массиву, разбивая длинные строки на несколько и подсчитывая длину самой длинной строки после разбивки.
Потом вывести, добавляя звёздочки и необходимое число пробелов в конце каждой.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы