社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Jquery

使用javascript jquery访问通过ajax返回的json数组中的嵌套键值[duplicate]

art vanderlay • 4 年前 • 1550 次点击  

我有一个包含对象和数组的嵌套数据结构。如何提取信息,即访问特定或多个值(或密钥)?

例如:

var data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

我怎么能进入 name 中第二项的 items ?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/44029
 
1550 次点击  
文章 [ 22 ]  |  最新文章 4 年前
Machavity pradeep gowda
Reply   •   1 楼
Machavity pradeep gowda    6 年前

使用矿灰是个好办法

前任:

var object = { 'a': { 'b': { 'c': 3 } } };                                                                                               
_.get(object, 'a.b.c');                                                                                             
// => 3  
Kamil Kiełczewski
Reply   •   2 楼
Kamil Kiełczewski    4 年前

这里是动态方法-你的“深”键是string 'items[1].name' (可以使用数组表示法 [i] 在任何级别)-如果键无效,则返回未定义。

let deep = (o,k) => {
  return k.split('.').reduce((a,c,i) => {
    let m=c.match(/(.*?)\[(\d*)\]/);
    if(m && a!=null && a[m[1]]!=null) return a[m[1]][+m[2]];
    return a==null ? a: a[c];
  },o)
}

var data = {
    code: 42,
    items: [
      { id: 1, name: 'foo'}, 
      { id: 2, name: 'bar'},
   ]
};

let deep = (o,k) => {
  return k.split('.').reduce((a,c,i) => {
    let m=c.match(/(.*?)\[(\d*)\]/);
    if(m && a!=null && a[m[1]]!=null) return a[m[1]][+m[2]];
    return a==null ? a: a[c];
  },o)
}

console.log( deep(data,'items[1].name') );
Manthan Patel
Reply   •   3 楼
Manthan Patel    5 年前

我的 stringjson 来自php文件,但我在这里指出 var . 当我直接将json带入 obj 它不会显示这就是为什么我把json文件

var obj=JSON.parse(stringjson); 所以在那之后我得到 message obj并显示在警告框中,然后我得到 data 它是json数组,存储在一个变量中 ArrObj 然后我读取数组的第一个对象,其键值如下 ArrObj[0].id

     var stringjson={
        "success": true,
        "message": "working",
        "data": [{
                  "id": 1,
                  "name": "foo"
         }]
      };

                var obj=JSON.parse(stringjson);
                var key = "message";
                alert(obj[key]);
                var keyobj = "data";
                var ArrObj =obj[keyobj];

                alert(ArrObj[0].id);
user7110739
Reply   •   4 楼
user7110739    6 年前

jQuery's grep 函数用于筛选数组:

var data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

$.grep(data.items, function(item) {
    if (item.id === 2) {
        console.log(item.id); //console id of item
        console.log(item.name); //console name of item
        console.log(item); //console item object
        return item; //returns item object
    }

});
// Object {id: 2, name: "bar"}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
pX0r
Reply   •   5 楼
pX0r    7 年前

解析任意json树的python、递归和函数方法:

handlers = {
    list:  iterate,
    dict:  delve,
    str:   emit_li,
    float: emit_li,
}

def emit_li(stuff, strong=False):
    emission = '<li><strong>%s</strong></li>' if strong else '<li>%s</li>'
    print(emission % stuff)

def iterate(a_list):
    print('<ul>')
    map(unravel, a_list)
    print('</ul>')

def delve(a_dict):
    print('<ul>')
    for key, value in a_dict.items():
        emit_li(key, strong=True)
        unravel(value)
    print('</ul>')

def unravel(structure):
    h = handlers[type(structure)]
    return h(structure)

unravel(data)

哪里 数据 是一个python列表(从json文本字符串解析):

data = [
    {'data': {'customKey1': 'customValue1',
           'customKey2': {'customSubKey1': {'customSubSubKey1': 'keyvalue'}}},
  'geometry': {'location': {'lat': 37.3860517, 'lng': -122.0838511},
               'viewport': {'northeast': {'lat': 37.4508789,
                                          'lng': -122.0446721},
                            'southwest': {'lat': 37.3567599,
                                          'lng': -122.1178619}}},
  'name': 'Mountain View',
  'scope': 'GOOGLE',
  'types': ['locality', 'political']}
]
Dinesh Pandiyan
Reply   •   6 楼
Dinesh Pandiyan    5 年前

以防万一,任何人在2017年或以后访问此问题,并寻找 容易记住 好的,这里有一篇详细的博客文章 Accessing Nested Objects in JavaScript 不会被愚弄

无法读取未定义的属性“foo” 错误

1。奥利弗·斯蒂尔的嵌套对象访问模式

最简单和最干净的方法是使用oliver steele的嵌套对象访问模式

const name = ((user || {}).personalInfo || {}).name;

用这个符号,你永远不会碰到

无法读取未定义的属性“name” .

你基本上检查用户是否存在,如果不存在,你就动态地创建一个空对象。这样,下一级键将 总是从存在的对象或空对象访问 ,但从未从未定义开始。

2。使用array reduce访问嵌套对象

为了能够访问嵌套数组,可以编写自己的数组,减少UTIL。

const getNestedObject = (nestedObj, pathArr) => {
    return pathArr.reduce((obj, key) =>
        (obj && obj[key] !== 'undefined') ? obj[key] : undefined, nestedObj);
}

// pass in your object structure as array elements
const name = getNestedObject(user, ['personalInfo', 'name']);

// to access nested array, just pass in array index as an element the path array.
const city = getNestedObject(user, ['personalInfo', 'addresses', 0, 'city']);
// this will return the city from the first address item.

还有一个优秀的类型处理最小库 typy 这一切都是为了你。

Ilyas karim Andrei Todorut
Reply   •   7 楼
Ilyas karim Andrei Todorut    6 年前

动态访问多级对象。

var obj = {
  name: "salut",
  subobj: {
    subsubobj: {
      names: "I am sub sub obj"
    }
  }
};

var level = "subobj.subsubobj.names";
level = level.split(".");

var currentObjState = obj;

for (var i = 0; i < level.length; i++) {
  currentObjState = currentObjState[level[i]];
}

console.log(currentObjState);

工作小提琴: https://jsfiddle.net/andreitodorut/3mws3kjL/

dabeng
Reply   •   8 楼
dabeng    7 年前

我不认为questizer只关心一个层次的嵌套对象,所以我展示了下面的演示来演示如何访问深嵌套json对象的节点。好吧,让我们找到ID为“5”的节点。

var data = {
  code: 42,
  items: [{
    id: 1,
    name: 'aaa',
    items: [{
        id: 3,
        name: 'ccc'
      }, {
        id: 4,
        name: 'ddd'
      }]
    }, {
    id: 2,
    name: 'bbb',
    items: [{
        id: 5,
        name: 'eee'
      }, {
        id: 6,
        name: 'fff'
      }]
    }]
};

var jsonloop = new JSONLoop(data, 'id', 'items');

jsonloop.findNodeById(data, 5, function(err, node) {
  if (err) {
    document.write(err);
  } else {
    document.write(JSON.stringify(node, null, 2));
  }
});
<script src="https://rawgit.com/dabeng/JSON-Loop/master/JSONLoop.js"></script>
Thiago C. S Ventura
Reply   •   9 楼
Thiago C. S Ventura    6 年前

老问题,但没有人提到洛达斯(只是强调)。

如果您已经在您的项目中使用了lodash,我想在一个复杂的示例中可以用一种优雅的方法来实现这一点:

选择1

_.get(response, ['output', 'fund', 'data', '0', 'children', '0', 'group', 'myValue'], '')

等同于:

选择2

response.output.fund.data[0].children[0].group.myValue

第一个和第二个选项的区别在于 选择1 如果路径中缺少(未定义)某个属性,则不会出现错误,它将返回第三个参数。

对于阵列滤波器,lodash有 _.find() 但我宁愿用普通的 filter() . 但我还是认为上面的方法 _.get() 在处理非常复杂的数据时非常有用。我过去面对的是复杂的API,很方便!

我希望它能对WHO正在寻找选项来操纵真正复杂的数据,这是标题所暗示的。

Mohan Dere
Reply   •   10 楼
Mohan Dere    7 年前

下划线js方式

它是一个javascript库,提供了一大堆有用的 functional programming 不扩展任何内置对象的帮助程序。

解决方案:

var data = {
  code: 42,
  items: [{
    id: 1,
    name: 'foo'
  }, {
    id: 2,
    name: 'bar'
  }]
};

var item = _.findWhere(data.items, {
  id: 2
});
if (!_.isUndefined(item)) {
  console.log('NAME =>', item.name);
}

//using find - 

var item = _.find(data.items, function(item) {
  return item.id === 2;
});

if (!_.isUndefined(item)) {
  console.log('NAME =>', item.name);
}
Bergi
Reply   •   11 楼
Bergi    8 年前

如果要查找满足特定条件的一个或多个对象,可以使用 query-js

//will return all elements with an id larger than 1
data.items.where(function(e){return e.id > 1;});
//will return the first element with an id larger than 1
data.items.first(function(e){return e.id > 1;});
//will return the first element with an id larger than 1 
//or the second argument if non are found
data.items.first(function(e){return e.id > 1;},{id:-1,name:""});

还有一个 single 和A singleOrDefault 他们的工作方式很像 first firstOrDefault 分别是。唯一的区别是如果 更多 找到多个匹配项。

有关查询JS的进一步解释,您可以从这里开始 post

Johnny
Reply   •   12 楼
Johnny    4 年前
var ourStorage = {


"desk":    {
    "drawer": "stapler"
  },
"cabinet": {
    "top drawer": { 
      "folder1": "a file",
      "folder2": "secrets"
    },
    "bottom drawer": "soda"
  }
};
ourStorage.cabinet["top drawer"].folder2; // Outputs -> "secrets"

//parent.subParent.subsubParent["almost there"]["final property"]

基本上,在展开的每个子代之间使用一个点,当对象名由两个字符串组成时,必须使用[“obj name”]表示法。否则,只要一个点就足够了;

来源: https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-javascript/accessing-nested-objects

要添加此项,访问嵌套数组的方式如下:

var ourPets = [
  {
    animalType: "cat",
    names: [
      "Meowzer",
      "Fluffy",
      "Kit-Cat"
    ]
  },
  {
    animalType: "dog",
    names: [
      "Spot",
      "Bowser",
      "Frankie"
    ]
  }
];
ourPets[0].names[1]; // Outputs "Fluffy"
ourPets[1].names[0]; // Outputs "Spot"

来源: https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-javascript/accessing-nested-arrays/

另一份描述上述情况的更有用的文件: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics#Bracket_notation

通过点行走访问属性: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors#Dot_notation

Koby Douek Ramakrishna
Reply   •   13 楼
Koby Douek Ramakrishna    6 年前

你可以用 lodash _get 功能:

var object = { 'a': [{ 'b': { 'c': 3 } }] };

_.get(object, 'a[0].b.c');
// => 3
Rudy Hinojosa
Reply   •   14 楼
Rudy Hinojosa    8 年前

我更喜欢jquery。它干净易读。

 $.each($.parseJSON(data), function (key, value) {
    alert(value.<propertyname>);
});
Andrejs
Reply   •   15 楼
Andrejs    9 年前

使用 JSONPATH 如果您愿意包括一个库,这将是最灵活的解决方案之一: https://github.com/s3u/JSONPath (节点和浏览器)

对于您的用例,json路径将是:

$..items[1].name

所以:

var secondName = jsonPath.eval(data, "$..items[1].name");
Evgeny
Reply   •   16 楼
Evgeny    6 年前

要访问嵌套属性,需要指定其名称,然后在对象中搜索。

如果你已经知道确切的路径,那么你可以像你这样在脚本中硬编码:

data['items'][1]['name']

这些也起作用-

data.items[1].name
data['items'][1].name
data.items[1]['name']

当你在手之前不知道确切的名字,或者用户是为你提供名字的人。然后需要通过数据结构进行动态搜索。有些人建议可以使用 for 循环,但有一种非常简单的方法可以使用 Array.reduce .

const data = { code: 42, items: [{ id: 1, name: 'foo' }, { id: 2, name: 'bar' }] }
const path = [ 'items', '1', 'name']
let result = path.reduce((a,v) => a[v], data)

路径是这样说的:首先取带键的对象 items ,这正好是一个数组。那就拿着 1 -st元素(0个索引数组)。最后一个带键的对象 name 在数组元素中,正好是字符串 bar .

如果你有很长的路,你甚至可以使用 String.split 让这一切变得更容易-

'items.1.name'.split('.').reduce((a,v) => a[v], data)

这只是简单的javascript,没有使用任何第三方库,如jquery或lodash。

Jon Chesterfield Alex KeySmith
Reply   •   17 楼
Jon Chesterfield Alex KeySmith    7 年前

这个问题已经很老了,所以作为当代的更新。随着ES2015的开始,有其他方法可以获得所需的数据。现在有一个特性叫做 对象解构 用于访问嵌套对象。

const data = {
  code: 42,
  items: [{
    id: 1,
    name: 'foo'
  }, {
    id: 2,
    name: 'bar'
  }]
};

const {
  items: [, {
    name: secondName
  }]
} = data;

console.log(secondName);

上面的例子创建了一个名为 secondName name 来自名为 items 孤独的人 , 表示跳过数组中的第一个对象。

值得注意的是,对于这个例子来说,它可能有点过头了,因为简单的数组访问更容易阅读,但是它在一般情况下分解对象时非常有用。

这是非常简短的介绍你的具体用例,破坏可以是一个不寻常的语法首先习惯。我建议你读书 Mozilla's Destructuring Assignment documentation 去了解更多。

Michał Perłakowski Khoa Bui
Reply   •   18 楼
Michał Perłakowski Khoa Bui    7 年前

对象和数组有很多内置的方法,可以帮助您处理数据。

注意:在我使用的许多例子中 arrow functions . 它们类似于 function expressions ,但它们将 this 重视词汇。

Object.keys() , Object.values() (ES 2017)和 Object.entries() (ES 2017)

object.keys() 返回对象键的数组, object.values() 返回对象值的数组,并且 object.entries() 以某种格式返回对象键和相应值的数组 [key, value] .

const obj = {
  a: 1
 ,b: 2
 ,c: 3
}

console.log(Object.keys(obj)) // ['a', 'b', 'c']
console.log(Object.values(obj)) // [1, 2, 3]
console.log(Object.entries(obj)) // [['a', 1], ['b', 2], ['c', 3]]

object.entries() 带for循环和解构赋值

const obj = {
  a: 1
 ,b: 2
 ,c: 3
}

for (const [key, value] of Object.entries(obj)) {
  console.log(`key: ${key}, value: ${value}`)
}

迭代 object.entries() 用一个 for-of loop destructuring assignment .

for of循环允许您迭代数组元素。语法是 for (const element of array) 我们可以替代 const 具有 var let ,但最好使用 康斯特 如果我们不打算修改 element )

解构赋值允许您从数组或对象中提取值并将它们赋给变量。在这种情况下 const [key, value] 也就是说,不是指定 [关键,价值] 数组到 要素 ,我们将该数组的第一个元素分配给 key 第二个元素 value . 相当于:

for (const element of Object.entries(obj)) {
  const key = element[0]
       ,value = element[1]
}

正如你所看到的,破坏使这更简单。

Array.prototype.every() Array.prototype.some()

这个 every() 方法返回 true 如果指定的回调函数返回 对于 每一个 数组的元素。这个 some() 方法返回 如果指定的回调函数返回 对于 一些 (至少一个)元素。

const arr = [1, 2, 3]

// true, because every element is greater than 0
console.log(arr.every(x => x > 0))
// false, because 3^2 is greater than 5
console.log(arr.every(x => Math.pow(x, 2) < 5))
// true, because 2 is even (the remainder from dividing by 2 is 0)
console.log(arr.some(x => x % 2 === 0))
// false, because none of the elements is equal to 5
console.log(arr.some(x => x === 5))

Array.prototype.find() Array.prototype.filter()

这个 find() 方法返回 第一 满足所提供回调函数的元素。这个 filter() 方法返回 全部的 满足所提供回调函数的元素。

const arr = [1, 2, 3]

// 2, because 2^2 !== 2
console.log(arr.find(x => x !== Math.pow(x, 2)))
// 1, because it's the first element
console.log(arr.find(x => true))
// undefined, because none of the elements equals 7
console.log(arr.find(x => x === 7))

// [2, 3], because these elements are greater than 1
console.log(arr.filter(x => x > 1))
// [1, 2, 3], because the function returns true for all elements
console.log(arr.filter(x => true))
// [], because none of the elements equals neither 6 nor 7
console.log(arr.filter(x => x === 6 || x === 7))

Array.prototype.map()

这个 map() 方法返回一个数组,其中包含对数组元素调用提供的回调函数的结果。

const arr = [1, 2, 3]

console.log(arr.map(x => x + 1)) // [2, 3, 4]
console.log(arr.map(x => String.fromCharCode(96 + x))) // ['a', 'b', 'c']
console.log(arr.map(x => x)) // [1, 2, 3] (no-op)
console.log(arr.map(x => Math.pow(x, 2))) // [1, 4, 9]
console.log(arr.map(String)) // ['1', '2', '3']

Array.prototype.reduce()

这个 reduce() 方法通过使用两个元素调用提供的回调函数将数组缩减为单个值。

const arr = [1, 2, 3]

// Sum of array elements.
console.log(arr.reduce((a, b) => a + b)) // 6
// The largest number in the array.
console.log(arr.reduce((a, b) => a > b ? a : b)) // 3

这个 约化() 方法接受可选的第二个参数,即初始值。当您调用的数组 约化() 可以有零或一个元素。例如,如果我们想要创建一个函数 sum() 它接受一个数组作为参数并返回所有元素的和,我们可以这样写:

const sum = arr => arr.reduce((a, b) => a + b, 0)

console.log(sum([]))     // 0
console.log(sum([4]))    // 4
console.log(sum([2, 5])) // 7
Community samael
Reply   •   19 楼
Community samael    6 年前

有时,使用字符串访问嵌套对象是可取的。简单的方法是第一个层次,例如

var obj = { hello: "world" };
var key = "hello";
alert(obj[key]);//world

但对于复杂的json,情况往往并非如此。随着json变得更加复杂,在json中查找值的方法也变得复杂。导航json的递归方法是最好的,如何利用递归取决于搜索的数据类型。如果涉及条件语句,则 json search 可以很好的使用工具。

如果要访问的属性已知,但路径很复杂,例如在这个对象中

var obj = {
 arr: [
    { id: 1, name: "larry" },    
    { id: 2, name: "curly" },
    { id: 3, name: "moe" }
 ]
};

你知道你想得到对象中数组的第一个结果,也许你想使用

var moe = obj["arr[0].name"];

但是,这将导致异常,因为没有具有该名称的对象的属性。能够使用它的解决方案是将对象的树方面展平。这可以递归地完成。

function flatten(obj){
 var root = {};
 (function tree(obj, index){
   var suffix = toString.call(obj) == "[object Array]" ? "]" : "";
   for(var key in obj){
    if(!obj.hasOwnProperty(key))continue;
    root[index+key+suffix] = obj[key];
    if( toString.call(obj[key]) == "[object Array]" )tree(obj[key],index+key+suffix+"[");
    if( toString.call(obj[key]) == "[object Object]" )tree(obj[key],index+key+suffix+".");   
   }
 })(obj,"");
 return root;
}

现在,复杂的物体可以变平。

var obj = previous definition;
var flat = flatten(obj);
var moe = flat["arr[0].name"];//moe

这里是一个 jsFiddle Demo 使用这种方法。

lukas.pukenis holographic-prin
Reply   •   20 楼
lukas.pukenis holographic-prin    10 年前

如果你想访问 item 从示例结构 id name ,不知道它在数组中的位置,最简单的方法是使用 underscore.js 图书馆:

var data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

_.find(data.items, function(item) {
  return item.id === 2;
});
// Object {id: 2, name: "bar"}

根据我的经验,用高阶函数代替 for for..in 循环产生的代码更容易推理,因此更易于维护。

就我的2美分。