【问题标题】:How to get the array value and object key values match irrespective of the order无论顺序如何,如何获取数组值和对象键值匹配
【发布时间】:2019-01-27 20:05:15
【问题描述】:

在值数组中

var legends =['some','key', 'value'];

具有相应 obj 值的图形;

var graph = {
  orgid: ['123', '123556', '456', '345', '2345'],
  some: [1500, 1500, 1500, 1500, 1500],
  key: [900, 900, 900, 900, 900],
  value: [1072, 1373, 946, 715, 276]
 };

我想提取仅包含数组中提到的键值的图形,以插入到另一个数组中

我已经执行了代码,但它只有在 obj 中提到的顺序中的键顺序相同时才有效

es5方式

var grphFilter = [];
var countRaw = 0; 
for (var key in graph) {
  if (key === legends[count] ) {
    grphFilter.push(graph[key]);
    count++;
  }
}

es6方式

let grphFilter = [];
let count = 0; 
const result = Object.entries(graph).forEach(function([key, value]) {
  if (key === legends[count]) {
    grphFilter.push(value);
    count++
  }
})

但它不适用于不按顺序排列的键。

var legendsNotOrder =['key', 'some', 'value'];

不考虑legends数组中的值的顺序,结果应该是最终结果,无论是legends还是legendsNotOrder

最终结果

var graphfiltered = [
  [1500, 1500, 1500, 1500, 1500],
  [900, 900, 900, 900, 900],
  [1072, 1373, 946, 715, 276]
];

【问题讨论】:

  • graphfiltered 的结构与您的graph(普通对象)不同(它是一个数组)。这背后的逻辑是什么?
  • 你想检查key是否是legends数组中的一个键,而不是if (key === legends[count])

标签: javascript arrays object ecmascript-6


【解决方案1】:

您可以遍历数组并仅从对象中获取所需的属性值。

var legends =['some','key', 'value'];

var graph = {orgid: ['123', '123556', '456', '345', '2345'],some: [1500, 1500, 1500, 1500, 1500],key: [900, 900, 900, 900, 900],value: [1072, 1373, 946, 715, 276]};
 
let filteredGraph = legends.map( cur => graph[cur])

console.log(filteredGraph)


//In case you have keys in legend which are not available in graph you can use below code

let filteredGraph = legends.filter( cur => graph[cur])

【讨论】:

  • 谢谢,它有效,但如果图例数组中有更多值,我必须使用过滤器删除未定义
  • @SwapnilSrivastava 我的回答涵盖了这种情况,并且只在 legends 数组上循环一次,如果您愿意,可以尝试一下。
  • @SwapnilSrivastava 我考虑了你所说的问题。无论如何,你可以看到更新的。您只需要将地图更改为过滤器
【解决方案2】:

使用 Object#entries、Array#reduce、Array#includes、Array#push

const legends=['some','key','value'];const graph={orgid:['123','123556','456','345','2345'],some:[1500,1500,1500,1500,1500],key:[900,900,900,900,900],value:[1072,1373,946,715,276]}

const res = Object.entries(graph)
.reduce((a,[k,v])=>{
  if(legends.includes(k)) a.push(v);
  return a;
}, []);

console.log(res);

【讨论】:

  • 不要将reducepush 一起使用。请改用mapfilter
  • @Bergi 为什么不呢?
  • 我认为这是因为该函数的本质是您将多个值“减少”为一个值,而这里您正在累积push()
  • 因为高级函数比原始函数更容易理解。为什么使用reduce 而不是简单的for 循环?
  • @Bergi 如果我决定使用map,我首先必须使用filter。我基本上会循环两次。在我个人看来,我将使用我认为最有效的解决方案。感谢您的反馈。如果您不同意我的解决方案,请随时投反对票。即使我应该(再次主观地)使用for,我也会尽可能使用 es6 功能。
【解决方案3】:

问题是您在当前迭代中使用legends 数组中的特定值检查key。您需要检查的是当前迭代中的key 是否等于该数组的任何值。

类似:

legends.includes(key)

这是一个完整的例子:

var legends = ['some', 'key', 'value'];

var graph = {
  orgid: ['123', '123556', '456', '345', '2345'],
  some: [1500, 1500, 1500, 1500, 1500],
  key: [900, 900, 900, 900, 900],
  value: [1072, 1373, 946, 715, 276]
};

var graphFilter = [];
for (var key in graph) {
  if (legends.includes(key)) {
    graphFilter[legends.indexOf(key)] = graph[key];
  }
}

console.log(graphFilter);

【讨论】:

  • var key in graph之后为什么不直接做if(key in graph) graphFilter.push(graph[key]);
  • @RobertRocha 为了保持秩序,OP 似乎想要这样做。
【解决方案4】:

您可以使用keys 在数组上循环,然后直接访问graph 对象。此外,您可以在对新数组执行 push 之前检查键是否为 valid

var legends = ['some', 'key', 'value', 'notkey'];

var graph = {
    orgid: ['123', '123556', '456', '345', '2345'],
    some: [1500, 1500, 1500, 1500, 1500],
    key: [900, 900, 900, 900, 900],
    value: [1072, 1373, 946, 715, 276]
 };
 
 let graphFilter = [];
 legends.forEach(x => graph[x] && graphFilter.push(graph[x]));
 console.log(graphFilter);

另一种选择是将filter()map() 组合在图表的条目上。

var legends = ['some', 'key', 'value', 'notkey'];

var graph = {
    orgid: ['123', '123556', '456', '345', '2345'],
    some: [1500, 1500, 1500, 1500, 1500],
    key: [900, 900, 900, 900, 900],
    value: [1072, 1373, 946, 715, 276]
 };
 
let graphFilter = Object.entries(graph)
     .filter(([k, v]) => legends.includes(k))
     .map(([k, v]) => v);

console.log(graphFilter);

【讨论】:

    【解决方案5】:

    ES6 一种带有reduce 的循环解决方案,它忽略legends 数组中的未知键:

    const legends = ['some', 'key', 'value', 'random_key'];
    
    const graph = {
        orgid: ['123', '123556', '456', '345', '2345'],
        some:  [1500, 1500, 1500, 1500, 1500],
        key:   [900, 900, 900, 900, 900],
        value: [1072, 1373, 946, 715, 276]
    };
    
    const result = legends.reduce((a, c) => {
        if (r = graph[c]) {
            a.push(r);
        }
        return a;
    }, []);
    
    console.log(result);

    一般来说,map + filter 通常可以替换为 reduce。担心,代码可能会变得更复杂。好处可能是优化(可能是“微”),这通常是不值得的。

    请注意,我在您的原始代码中将var 替换为const

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多