从对象数组中删除动态键

4

这个之前的问题与我感兴趣的最接近。我尝试了几种indexOf()和filter()的变体,但都没有成功。

我有一个对象数组 (exampleDat):

[{id:1, value:"100", name:"dog", D1: 10, D2: 67, D3: 33},
{id:2, value:"200", name:"cat", D1: 66, D2: 41, D3: 34},
{id:3, value:"300", name:"fish", D1: 23, D2: 45, D3:},
{id:4, value:"400", name:"mouse", D1: 13, D2: 55, D3:},
{id:5, value:"500", name:"snake", D1: 7, D2: 9, D3:}]

在另一个函数中,我返回一个我需要的“key”数组。该数组会动态地改变,因此不可能将它们全部打出来。例如,以下任何示例都是可行的,
useThese1 = ['D1','D2'] //Want exampleDat returned with only these key,value 'columns' returned
useThese2 = ['id','D1','D2','D3'] //Want exampleDat return with only these key,value 'columns' returned
useThese3 = ['value','D2','D3'] //Want exampleDat returned with only these key,value 'columns' returned

我需要动态地将useThese数组中的值映射到exampleDat数组中。

如果我知道确切的列,我可以手动输入如下:

exampleDat.map(d => {return {D1: d.D1, D2: d.D2}})

但是我需要类似这样的东西:
dat.map(d => useThese1.map(g =>  {return {something?}}) ???

在R中,简单易行的方法就是exampleDat[,colnames(exampleDat) %in% useThese1]
6个回答

5

您可以映射新的按键。

const
    mapWith = (array, keys) => array.map(o => Object.fromEntries(keys.map(k => [k, o[k]]))),
    data = [{ id: 1, value: "100", name: "dog", D1: 10, D2: 67, D3: 33 }, { id: 2, value: "200", name: "cat", D1: 66, D2: 41, D3: 34 }, { id: 3, value: "300", name: "fish", D1: 23, D2: 45, D3:97}, { id: 4, value: "400", name: "mouse", D1: 13, D2: 55, D3:98}, { id: 5, value: "500", name: "snake", D1: 7, D2: 9, D3:99}],
    result1 = mapWith(data, ['D1', 'D2']),
    result2 = mapWith(data, ['id', 'D1', 'D2', 'D3']),
    result3 = mapWith(data, ['value', 'D2', 'D3']);

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

Object.fromEntries 是比较新的特性,但很容易进行 polyfill。


这是比我的更好的方法,不确定为什么我没有想到! - T.J. Crowder

3

这是我的解决方案。它使用ES5 Javascript函数。

const selectKeys = (keys, data) => {
    return data.map(item => keys.reduce((prev, key) => {
        prev[key] = item[key]
        return prev
    }, {}))
}

const selData1 = selectKeys(useThese1, data)
const selData2 = selectKeys(useThese2, data)
const selData3 = selectKeys(useThese3, data)


1
您可以做如下操作:

您可以这样做

const arr = [
  { id: 1, value: "100", name: "dog", D1: 10, D2: 67, D3: 33 },
  { id: 2, value: "200", name: "cat", D1: 66, D2: 41, D3: 34 },
  { id: 3, value: "300", name: "fish", D1: 23, D2: 45, D3: 34 },
  { id: 4, value: "400", name: "mouse", D1: 13, D2: 55, D3: 34 },
  { id: 5, value: "500", name: "snake", D1: 7, D2: 9, D3: 34 }
];

function dynamicFilter(data, requiredKeys) {
    return data.map((item) => {
        const result = {};
        requiredKeys.forEach(key => result[key] = item[key]);
        return result;
    });
}

console.log(dynamicFilter(arr, ['D1','D2']));
console.log(dynamicFilter(arr, ['id','D1','D2','D3']));

1
你可以像这样做:

const arr = [{id:1, value:"100", name:"dog", D1: 10, D2: 67, D3: 33}, {id:2, value:"200", name:"cat", D1: 66, D2: 41, D3: 34}, {id:3, value:"300", name:"fish", D1: 23, D2: 45, D3:11}, {id:4, value:"400", name:"mouse", D1: 13, D2: 55, D3:11}, {id:5, value:"500", name:"snake", D1: 7, D2: 9, D3:11}];

const useThese1 = ['D1','D2'];
const useThese2 = ['id','D1','D2','D3'];
const useThese3 = ['value','D2','D3'];

const getResult = (keys) => arr.map(v => keys.reduce((a, c) => (a[c] = v[c], a), {}));

[useThese1, useThese2, useThese3].forEach(v => console.log(getResult(v)));


0
这是一种命令式的方法来实现它。使用ES6数组方法可以缩短代码。

let exampleDat = [
  {id:1, value:"100", name:"dog", D1: 10, D2: 67, D3: 33},
  {id:2, value:"200", name:"cat", D1: 66, D2: 41, D3: 34},
  {id:3, value:"300", name:"fish", D1: 23, D2: 45, D3: 8},
  {id:4, value:"400", name:"mouse", D1: 13, D2: 55, D3: 8},
  {id:5, value:"500", name:"snake", D1: 7, D2: 9, D3: 8}
],
useThese1 = ['D1','D2']

function getColumns(data, useWhich){
  let result = [];
  for(let row of data){
    let keys = Object.keys(row);
    let filteredRow = {};
    for(let key of keys){
      if(useWhich.includes(key)){
        filteredRow[key] = row[key];
      }
    }
    result.push(filteredRow);  
  }
  return result;
}

console.log(getColumns(exampleDat, useThese1));


0

以下是一份“白痴版”的答案。
(更详细的变量名称帮助我理解算法的工作原理。)

const
  selectColumns = (unfilteredData, colsToKeep) => 
    unfilteredData.map(row =>
      Object.fromEntries(colsToKeep.map( col => [col, row[col]] )
    )
  ),

  data = [
    { id: 1, value: "100", name: "dog", D1: 10, D2: 67, D3: 33 },
    { id: 2, value: "200", name: "cat", D1: 66, D2: 41, D3: 34 },
    { id: 3, value: "300", name: "fish", D1: 23, D2: 45, D3:97 },
    { id: 4, value: "400", name: "mouse", D1: 13, D2: 55, D3:98 },
    { id: 5, value: "500", name: "snake", D1: 7, D2: 9, D3:99 }
  ],

  colNames1 = ['D1', 'D2'],
  result1 = selectColumns(data, colNames1);
console.log(result1);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接