可以说我的对象如下所示。它混合了不同的数组和父对象,没有层次顺序。例如
"person": {
"id": 12345,
"name": "John Doe",
"emergencyContacts": [
{
"name": "Jane Doe",
"phone": "888-555-1212",
"relationship": "spouse",
"moreDetails": {
"id": 12345,
"phones": {},
"home": "800-123-4567",
"mobile": "877-123-1234"
}
},
{
"name": "Justin Doe",
"phone": "877-123-1212",
"relationship": "parent",
"mobile": "877-123-1234"
}
],
"workContacts": [
{
"name": "Jane Doe",
"phone": "888-555-1212",
"relationship": "spouse",
"moreworkDetails": {
"id": 12345,
"phones": {},
"home": "800-123-4567",
"mobile": "877-123-1234"
}
},
{
"name": "Justin Doe",
"phone": "877-123-1212",
"relationship": "parent",
"mobile": "877-123-1234"
}
]
}
我希望能够搜索person
的整个对象并带回键mobile
的值。我猜想该对象需要展平,并创建一个新数组,并用“唯一”手机号码列表创建该数组,例如
var mobile = {
0: 888-555-1212,
1: 800-123-4567,
2: 877-123-1234,
3: 083-111-3346
}
我已经在纯js和lodash中搜索了解决方案,但是找到的每个对象都知道父对象的名称和数组的深度-假设父对象和深度可以是无限的(这将其排除在问题{{3之外}})。任何帮助将不胜感激。谢谢
答案 0 :(得分:0)
您将需要一个递归函数。有关说明,请查看评论
let person = {
"id": 12345,
"name": "John Doe",
"emergencyContacts": [{
"name": "Jane Doe",
"phone": "888-555-1212",
"relationship": "spouse",
"moreDetails": {
"id": 12345,
"phones": {},
"home": "800-123-4567",
"mobile": "877-123-1234"
}
},
{
"name": "Justin Doe",
"phone": "877-123-1212",
"relationship": "parent",
"mobile": "877-123-1234"
}
],
"workContacts": [{
"name": "Jane Doe",
"phone": "888-555-1212",
"relationship": "spouse",
"moreworkDetails": {
"id": 12345,
"phones": {},
"home": "800-123-4567",
"mobile": "877-123-1236"
}
},
{
"name": "Justin Doe",
"phone": "877-123-1212",
"relationship": "parent",
"mobile": "877-123-1235"
}
]
}
let arrys = [];
//iterate the object
function recursive(obj, key) {
//iterate the object
for (let keys in obj) {
// check if the key name is same as the desired one
if (keys === key) {
// then push the value to an array
arrys.push(obj[keys])
} else {
// if the value of a key is an array & if it is not empty
if (Array.isArray(obj[keys]) && obj[keys].length > 0) {
// iterate the array. in each iteration you will get the object
// example emergencyContacts. In each iteration
// call the same function with new data
obj[keys].forEach(function(item) {
// pass that object to the same function
recursive(item, key)
})
}
// if the value is an object then again call the same function
else if (typeof obj[keys] === 'object') {
recursive(obj[keys], key)
}
}
}
}
recursive(person, 'mobile');
//create object from the array
let newObj = {}
for (let m = 0; m < arrys.length; m++) {
newObj[m] = arrys[m]
}
console.log(newObj)
答案 1 :(得分:0)
您不需要递归。您可以使用while
循环来完成此操作:
function searchFor(what, where) {
const stack = [where];
const result = [];
while (stack.length) {
const item = stack.pop();
if (Array.isArray(item)) {
item.forEach(el => stack.push(el));
continue;
}
if (item && typeof item === "object")
Object.entries(item).forEach(([key, value]) =>
key === what ?
result.push(value) :
stack.push(value)
)
}
return result;
}
答案 2 :(得分:0)
我用从我自己的库中无耻地偷来的代码概括了一下:goodcore
我选择了递归方法,因为我相信尽管代码更多,但代码更容易分析。
let obj = {
"id": 12345,
"name": "John Doe",
"emergencyContacts": [{
"name": "Jane Doe",
"phone": "888-555-1212",
"relationship": "spouse",
"moreDetails": {
"id": 12345,
"phones": {},
"home": "800-123-4567",
"mobile": "877-123-1234"
}
},
{
"name": "Justin Doe",
"phone": "877-123-1212",
"relationship": "parent",
"mobile": "877-123-1234"
}
],
"workContacts": [{
"name": "Jane Doe",
"phone": "888-555-1212",
"relationship": "spouse",
"moreworkDetails": {
"id": 12345,
"phones": {},
"home": "800-123-4567",
"mobile": "877-123-1236"
}
},
{
"name": "Justin Doe",
"phone": "877-123-1212",
"relationship": "parent",
"mobile": "877-123-1235"
}
]
};
function isObject(it) {
return it !== null && typeof it === "object";
}
function isArray(it) {
return Array.isArray ? Array.isArray(it) : Object.prototype.toString.call(it) === "[object Array]";
}
function forEach(target, fn) {
if(isArray(target)) {
target.forEach(fn);
} else {
Object.entries(target).forEach(([key, value]) => fn(value, key));
}
}
function objReduce(obj, fn, acc) {
let a = acc;
forEach(obj, (value, key) => {
if(isObject(value) || isArray(value)) {
a = objReduce(value, fn, a);
}
a = fn(a, value, key);
});
return a;
}
objReduce(obj, (acc, cur, key) => {
if(key === "mobile") {
acc.push(cur);
}
return acc;
}, []);
基本上,它的作用是创建一个对象reduce函数,该函数将遍历所有属性并在其上运行累加器函数,就像Array.prototype.reduce对数组所做的那样。由于它可以任意处理数组和对象,因此需要一些代码。
答案 3 :(得分:0)
returnValuesForAttribute = (attr) => {
let mobile = {};
let index = 0;
Object.values(person).map(first_level => {
if (Array.isArray(first_level)) {
first_level.map(el => {
if (Object.keys(el).includes(attr)) {
mobile[index] = el[attr];
index++;
}
Object.values(el).map(second_level => {
if (typeof second_level === 'object' && second_level[attr]) {
mobile[index] = second_level[attr];
index++;
}
})
})
}
});
return mobile;
}
returnValuesForAttribute('mobile');
输出:{0:“ 877-123-1234”,1:“ 877-123-1234”,2:“ 877-123-1234”,3:“ 877-123-1234”}
答案 4 :(得分:0)
检测深度嵌套对象中的键并返回键的值。
function getPropFromObj(obj, prop) {
let valueToFindByKey;
if (!Array.isArray(obj) && obj !== null && typeof obj === "object") {
if (obj.hasOwnProperty(prop)) {
valueToFindByKey = obj[prop];
console.log(valueToFindByKey);
} else {
let i;
for (i = 0; i < Object.keys(obj).length; i++) {
getPropFromObj(obj[Object.keys(obj)[i]], prop);
}
}
}
return null;
}
const objToInvestigate = {
employeeInformation: {
employees: {
name: "venky",
age: 27,
job: "Frontend Developer",
},
},
};
getPropFromObj(objToInvestigate, "name");