JS: Удалить ключ объекта, если все вложенные значения равны нулю - PullRequest
4 голосов
/ 16 апреля 2019

Из заданной структуры данных (файл json) мне в основном нужно отобразить таблицу.Пустые строки и / или столбцы не должны отображаться.Я довольно новичок в JavaScript и пробовал разные подходы (преобразование в массив и использование .map (), redu (), .filter (), lodash и т. Д.) Без успеха.Я даже не знаю, как лучше решить проблему.(Или какими возможными поисковыми терминами будут.)

Ни «ключи строки» (например: mo, tu, we, th, fr), ни «ключи столбца» (john, hane, doe) не известны иможет варьироваться.

Полный пример: https://jsbin.com/rafeyasena/edit?js,output

"groupA": {
    "mo": { "john": 8, "jane": 5, "doe": null },
    "tu": { "john": 8, "jane": 5, "doe": null },
    "we": { "john": 5, "jane": 9, "doe": null },
    "th": { "john": 6, "jane": 3, "doe": null },
    "fr": { "john": null, "jane": null, "doe": null }
  }

Возможная результирующая структура данных

const header = ["John", "Jane"];
const content = [
 "mo": {[ 8, 5 ]},
 "tu": {[ 8, 5 ]},
 "we": {[ 5, 9 ]},
 "th": {[ 6, 3 ]}
]

Ожидаемый результат (Front-end, React):

   | John | Jane |
---|------|--------
mo |  8   |  5   |
tu |  8   |  5   |
we |  5   |  9   |
th |  6   |  3   |

То, что я пробовал до сих пор: я смог удалить все значения null и соответствующий ключ, если он больше не содержит ключей / значений ( Удалить нулевые значения во вложенных объектах javascript ) - побудить меня выяснить все оставшиеся ключи для построения заголовка таблицы.(В приведенном ниже примере это будут только Джон и Джейн. Таким образом, в основном это способ перебора всех ключей и запись каждого ключа, который существует хотя бы один раз).Поэтому мои текущие данные выглядят так (но я не уверен, что это лучший способ):

"groupA": {
    "mo": { "john": 8, "jane": 5, },
    "tu": { "john": 8, "jane": 5, },
    "we": { "john": 5, "jane": 9, },
    "th": { "john": 6, "jane": 3, }
  }

Ответы [ 2 ]

0 голосов
/ 17 апреля 2019

Я думаю, что создание этого последнего формата (с удаленными нулями) является очень полезным первым шагом. Оттуда вы можете написать что-то вроде этого, чтобы перевести это в вариант целевого формата:

const uniqKeys = (obj) => [... new Set(Object.values(obj).flatMap(Object.keys))]

const transform = (group, headers = uniqKeys(group)) => ({
  headers,
  content: Object.entries(group).reduce(
    (a, [k, v]) => ({...a, [k]: headers.map(h => v[h])}),
    {}
  )
})


const groupA = {mo: {john: 8, jane: 5}, tu: {john: 8, jane: 5}, we: {john: 5, jane: 9}, th: {john: 6, jane: 3}}

console.log(transform(groupA))

Обратите внимание, что цель немного отличается от вашего запроса, так как ваш пример контента не является законным JS ({[ 8, 5 ]} не имеет смысла), но я думаю, что он отражает его дух, возвращая что-то вроде:

{
  headers: ['john', 'jane'],
  content: {
    mo: [8, 5],
    tu: [8, 5],
    we: [5, 9],
    th: [6, 3]
  }
}

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

0 голосов
/ 16 апреля 2019

Я бы просто представил данные в виде двумерного массива (это облегчает рендеринг):

 const columnNames = [""];
 const rows = [columnNames];

  for(const [rowName, values] of Object.entries(groupA)) {
     const row = [rowName];
     for(const [columnName, value] of Object.entries(values)) {
        let position = columnNames.indexOf(columnName);
        if(value === null) continue;
        if(position === -1)
          position = columnNames.push(columnName) - 1;
        row[position] = value;
     }
     rows.push(row);
 }

 // just some debugging:   
 console.log( rows.map(row => row.map(it => (it || "").padStart(10)).join("|")).join("\n") );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...