如何按索引而不是名称映射 JSON 属性

Posted

技术标签:

【中文标题】如何按索引而不是名称映射 JSON 属性【英文标题】:How to Map JSON Property by Index rather than Name 【发布时间】:2019-04-18 05:32:18 【问题描述】:

我有 web 应用程序,我有以下 JSON 数组:

var data=[ 
  "category" : "Search Engines", "hits" : 5, "bytes" : 50189 ,
  "category" : "Content Server", "hits" : 1, "bytes" : 17308 ,
  "category" : "Content Server", "hits" : 1, "bytes" : 47412 ,
  "category" : "Search Engines", "hits" : 1, "bytes" : 7601 ,
  "category" : "Business", "hits" : 1, "bytes" : 2847 ,
  "category" : "Content Server", "hits" : 1, "bytes" : 24210 ,
  "category" : "Internet Services", "hits" : 1, "bytes" : 3690 ,
  "category" : "Search Engines", "hits" : 6, "bytes" : 613036 ,
  "category" : "Search Engines", "hits" : 1, "bytes" : 2858  
];

我想在一个单独的表中获得hits 字段,例如 var hits = [5,1,1,1,1,1,1,6,1]

我知道data.map(x=>x.hits) 但我在 json 中的属性名称是动态的。我事先不知道我的财产名称。所以我需要在 Json 中使用属性索引。

我知道可以通过 json 循环使用,

但是有没有办法在一个语句中获取所有 hits 而没有任何循环?

【问题讨论】:

使用 Object.keys() 获取 JSON 对象的所有可用属性的数组。然后你可以遍历它们而不管它们的值是什么 没有“JSON 数组”或“JSON 对象”之类的东西。 JSON 是一些数据结构的文本表示(它可以是数组、对象或原始类型,也可以是数字或字符串)。您发布的文本是 javascript 代码,而不是 JSON。 你说我不知道我的属性名称,但你想要获得所有命中你是什么意思? 似乎依赖于特定顺序的键非常脆弱。 【参考方案1】:

像这样:

let prop = 'hits';

data.map(x => x[prop]);

prop 重新分配为所需的属性名称。

【讨论】:

【参考方案2】:

sn-p 是:

var data=[ 
  "category" : "Search Engines", "hits" : 5, "bytes" : 50189 ,
  "category" : "Content Server", "hits" : 1, "bytes" : 17308 ,
  "category" : "Content Server", "hits" : 1, "bytes" : 47412 ,
  "category" : "Search Engines", "hits" : 1, "bytes" : 7601 ,
  "category" : "Business", "hits" : 1, "bytes" : 2847 ,
  "category" : "Content Server", "hits" : 1, "bytes" : 24210 ,
  "category" : "Internet Services", "hits" : 1, "bytes" : 3690 ,
  "category" : "Search Engines", "hits" : 6, "bytes" : 613036 ,
  "category" : "Search Engines", "hits" : 1, "bytes" : 2858  
];

var idx = 1; // key2

var key = Object.keys(data)[idx];
value = o[key]

console.log(key,value); // key2 value2

你也可以用这个:

    var data=[ 
      "category" : "Search Engines", "hits" : 5, "bytes" : 50189 ,
      "category" : "Content Server", "hits" : 1, "bytes" : 17308 ,
      "category" : "Content Server", "hits" : 1, "bytes" : 47412 ,
      "category" : "Search Engines", "hits" : 1, "bytes" : 7601 ,
      "category" : "Business", "hits" : 1, "bytes" : 2847 ,
      "category" : "Content Server", "hits" : 1, "bytes" : 24210 ,
      "category" : "Internet Services", "hits" : 1, "bytes" : 3690 ,
      "category" : "Search Engines", "hits" : 6, "bytes" : 613036 ,
      "category" : "Search Engines", "hits" : 1, "bytes" : 2858  
    ];

for(var prop in data) 
  console.log(prop,data[prop]);  

【讨论】:

【参考方案3】:

您可以有两种不同的方法。如果密钥是动态的,但您通过变量知道您正在寻找的密钥是什么:

const keyname = 'hits';
data.map(x => x[keyname])

其中 keyname 是您根据需要设置的变量。

如果由于某些原因它只能通过索引才能工作,那么由于这个公式,您必须从索引中获取键名:

const j = 0; // or increment j through a for loop
const index = 3; // the index of the key you need
let keyname = Object.keys(data[j])[index];
data.map(x => x[keyname]);

【讨论】:

【参考方案4】:

您可以利用Objcet.keys()生成的键数组的位置:

var data = [ 
  "category" : "Search Engines", "hits" : 5, "bytes" : 50189 ,
  "category" : "Content Server", "hits" : 1, "bytes" : 17308 ,
  "category" : "Content Server", "hits" : 1, "bytes" : 47412 ,
  "category" : "Search Engines", "hits" : 1, "bytes" : 7601 ,
  "category" : "Business", "hits" : 1, "bytes" : 2847 ,
  "category" : "Content Server", "hits" : 1, "bytes" : 24210 ,
  "category" : "Internet Services", "hits" : 1, "bytes" : 3690 ,
  "category" : "Search Engines", "hits" : 6, "bytes" : 613036 ,
  "category" : "Search Engines", "hits" : 1, "bytes" : 2858  
];

var res = data.map(item => 
  var k = Object.keys(item);
  return item[k[1]];
);
console.log(res);

【讨论】:

【参考方案5】:

首先您需要使用 Object.keys 获取密钥。然后只需放一个 Map 功能即可完成您的任务。

var data=[ 
      "category" : "Search Engines", "hits" : 5, "bytes" : 50189 ,
      "category" : "Content Server", "hits" : 1, "bytes" : 17308 ,
      "category" : "Content Server", "hits" : 1, "bytes" : 47412 ,
      "category" : "Search Engines", "hits" : 1, "bytes" : 7601 ,
      "category" : "Business", "hits" : 1, "bytes" : 2847 ,
      "category" : "Content Server", "hits" : 1, "bytes" : 24210 ,
      "category" : "Internet Services", "hits" : 1, "bytes" : 3690 ,
      "category" : "Search Engines", "hits" : 6, "bytes" : 613036 ,
      "category" : "Search Engines", "hits" : 1, "bytes" : 2858  
    ];
var KeyName=Object.keys(data[0])[1]
data.map(x => x[KeyName]);

【讨论】:

【参考方案6】:

如果我正确理解您的问题,您不知道data 数组中的对象是否具有hits 属性。或者它可能会拼写不同。

这是处理这种情况的一种方法

var data=[ 
  "category" : "Search Engines", "hits" : 5, "bytes" : 50189 ,
  "category" : "Content Server", "HITS" : 1, "bytes" : 17308 ,
  "category" : "Content Server", "hit" : 1, "bytes" : 47412 ,
  "category" : "Search Engines", "HIT" : 1, "bytes" : 7601 ,
  "category" : "Business", "bytes" : 2847 ,
  "category" : "Content Server", "hits" : 1, "bytes" : 24210 ,
  "category" : "Internet Services", "hits" : 1, "bytes" : 3690 ,
  "category" : "Search Engines", "hits" : 6, "bytes" : 613036 ,
  "category" : "Search Engines", "hits" : 1, "bytes" : 2858  
];


data.forEach(function(obj)
  //first, get an array of all availble keys in current element
  var keys = Object.keys(obj);
  
  //now we loop through all obtained keys
  keys.forEach(function(key)
  
    // the following line will match HIT/HITS/hit/hits
    if(key.toUpperCase().indexOf("HIT")>-1) 
       console.log("found hits: " , obj[key]);
    
  );

);

【讨论】:

【参考方案7】:

如果我理解你的意思是正确的,你的数据是一个数组,这个数组包含一些值。但也许其中一个没有hits 的属性。那么,您不想使用map 方法,因为结果可能包含undefined 值?

如果是你的问题,你可以尝试映射后使用filter方法。像这样:

    var arr = [
        
            'hits': 1
        ,
        
            'hits': 2
        ,
        
            'foo': 'bar'
        ,
        
            'hits': 3
        ,
        
            'hits': 4
        
    ];

    var hits = arr.map(x => x.hits).filter(x => x);

    console.log(hits);

映射后的结果应该是:

[1, 2, 未定义, 3, 4]

然后,我们需要将其过滤为:

[1, 2, 3, 4]

【讨论】:

以上是关于如何按索引而不是名称映射 JSON 属性的主要内容,如果未能解决你的问题,请参考以下文章

如何在asp.net的GridView中按列名而不是按索引获取单元格值

SQL JSON PATH 如何在从较大的 json 集中提取后按索引访问 json 数组

如何使用 Django 功能而不是所有键来索引刚刚选择的 json 键?

如何使用 Hive 在 Dart 中按值(而不是按索引)读取/更新/删除?

elasticsearch的映射

在弹性搜索中将Json字段存储为字符串吗?