lodash-如果所有值都为空,则从数据表(2D矩阵)中删除列

时间:2019-02-08 19:00:27

标签: javascript lodash

我有一个像这样的2D矩阵,其中第一行是列名,其他行是值。

var datatable = [
  ["a", "b",   "c",   "d"],  //first row are columns names
  [ 1,   0,     null,  3 ],  //other rows are values
  [ 6,   null,  null,  8 ]
];

当所有值均为null时,我想删除列,如下所示:

var datatable = [
  ["a", "b",   "d"],  //first row are columns names
  [ 1,   0,     3 ],  //other rows are values
  [ 6,   null,  8 ]
];

行数和列数可以变化。如果有一种紧凑而又快速的方法来用lodash来实现,那是完美的。

4 个答案:

答案 0 :(得分:3)

您可以首先获取具有所有null值的列,然后过滤行。

var datatable = [["a", "b", "c", "d"], [1, 0, null, 3], [6, null, null, 8]],
    cols = datatable
        .slice(1)                                                   // omit header
        .reduce((r, a) => a.map((v, i) => r[i] || v !== null), []);

datatable = datatable.map(a => a.filter((_, i) => cols[i]));

console.log(datatable);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:3)

使用.flow()创建一个函数,该函数使用_.unzip()转置数组,拒绝具有所有null值的数组,然后将数组解压缩为原始格式:

const { flow, partialRight: pr, unzip, reject, tail, every, isNull } = _; // convert to imports

const fn = flow(
  unzip,
  pr(reject, flow(tail, pr(every, isNull))),
  unzip,
);

const datatable = [
  ["a", "b",   "c",   "d"],  //first row are columns names
  [ 1,   0,     null,  3 ],  //other rows are values
  [ 6,   null,  null,  8 ]
];

const result = fn(datatable);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

还有terser lodash / fp解决方案:

const { flow, unzip, reject, tail, every, isNull } = _; // convert to imports

const fn = flow(
  unzip,
  reject(flow(
    tail,
    every(isNull)
  )),
  unzip,
);

const datatable = [
  ["a", "b",   "c",   "d"],  //first row are columns names
  [ 1,   0,     null,  3 ],  //other rows are values
  [ 6,   null,  null,  8 ]
];

const result = fn(datatable);

console.log(result);
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>

答案 2 :(得分:2)

您在这里使用map()filter()some()

var datatable = [
  ["a", "b",   "c",   "d"],
  [ 1,   0,     null,  3 ],
  [ 6,   null,  null,  8 ]
];

let res = datatable.map(
  x => x.filter((_, idx) => datatable.slice(1).some(arr => arr[idx] !== null))
);

console.log(res);

答案 3 :(得分:1)

代码稍长,但想法相似。

var datatable = [
  ["a", "b", "c", "d"],
  [1, 0, null, 3],
  [6, null, null, 8]
];

/* first create a simple key val map as {a:[1,6],b:[0,null] etc to weed out the keys with all nulls */

let keyValMap = datatable.reduce((acc,arr,index) => {
 if(index===0) {
  arr.forEach(key => {
   if(!acc[key])
    acc[key]=[]
  });
 } else {
  Object.keys(acc).map((key,index) => acc[key].push(arr[index])); 
 }
 return acc;
},{});

// now extract only those keys that do not have every element as null
let validKeys = Object.keys(keyValMap).filter(key => !keyValMap[key].every(i => i===null));

// pivot back from keyValMap the values based on validKeys
let updatedDataTable = [validKeys,  ...validKeys.map(key =>  keyValMap[key]).reduce((acc,val)=>{
  val.forEach((elem,i) => {
    if(!acc[i]) acc[i]=[];
    acc[i].push(elem)
  });
  return acc;
 },[]) ]

console.log(updatedDataTable);