Har*_*rry 60 javascript underscore.js
假设我有一个对象:
[
{
'title': "some title"
'channel_id':'123we'
'options': [
{
'channel_id':'abc'
'image':'http://asdasd.com/all-inclusive-block-img.jpg'
'title':'All-Inclusive'
'options':[
{
'channel_id':'dsa2'
'title':'Some Recommends'
'options':[
{
'image':'http://www.asdasd.com' 'title':'Sandals'
'id':'1'
'content':{
...
Run Code Online (Sandbox Code Playgroud)
我想找到id为1的一个对象.是否有类似这样的函数?我可以使用Underscore的_.filter方法,但我必须从顶部开始并过滤掉.
Zac*_*ach 68
递归是你的朋友.我更新了函数以考虑属性数组:
function getObject(theObject) {
var result = null;
if(theObject instanceof Array) {
for(var i = 0; i < theObject.length; i++) {
result = getObject(theObject[i]);
if (result) {
break;
}
}
}
else
{
for(var prop in theObject) {
console.log(prop + ': ' + theObject[prop]);
if(prop == 'id') {
if(theObject[prop] == 1) {
return theObject;
}
}
if(theObject[prop] instanceof Object || theObject[prop] instanceof Array) {
result = getObject(theObject[prop]);
if (result) {
break;
}
}
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
更新jsFiddle:http://jsfiddle.net/FM3qu/7/
hai*_*aka 18
如果要在搜索对象时获取id为1的第一个元素,可以使用此函数:
function customFilter(object){
if(object.hasOwnProperty('id') && object["id"] == 1)
return object;
for(var i=0; i<Object.keys(object).length; i++){
if(typeof object[Object.keys(object)[i]] == "object"){
var o = customFilter(object[Object.keys(object)[i]]);
if(o != null)
return o;
}
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
如果要获取id为1的所有元素,则(所有id为1的元素都存储在结果中):
function customFilter(object, result){
if(object.hasOwnProperty('id') && object.id == 1)
result.push(object);
for(var i=0; i<Object.keys(object).length; i++){
if(typeof object[Object.keys(object)[i]] == "object"){
customFilter(object[Object.keys(object)[i]], result);
}
}
}
Run Code Online (Sandbox Code Playgroud)
Cer*_*nce 18
另一个(有点傻)的选择是利用 的自然递归性质JSON.stringify,并在字符串化过程中向它传递一个在每个嵌套对象上运行的替换函数:
const input = [{
'title': "some title",
'channel_id': '123we',
'options': [{
'channel_id': 'abc',
'image': 'http://asdasd.com/all-inclusive-block-img.jpg',
'title': 'All-Inclusive',
'options': [{
'channel_id': 'dsa2',
'title': 'Some Recommends',
'options': [{
'image': 'http://www.asdasd.com',
'title': 'Sandals',
'id': '1',
'content': {}
}]
}]
}]
}];
console.log(findNestedObj(input, 'id', '1'));
function findNestedObj(entireObj, keyToFind, valToFind) {
let foundObj;
JSON.stringify(entireObj, (_, nestedValue) => {
if (nestedValue && nestedValue[keyToFind] === valToFind) {
foundObj = nestedValue;
}
return nestedValue;
});
return foundObj;
};Run Code Online (Sandbox Code Playgroud)
Abh*_*602 14
对我有用的是这种懒惰的方法,而不是算法上的懒惰;)
if( JSON.stringify(object_name).indexOf("key_name") > -1 ) {
console.log("Key Found");
}
else{
console.log("Key not Found");
}
Run Code Online (Sandbox Code Playgroud)
oll*_*lle 12
如果你对 ES6 很感兴趣,你可以使用
const findByKey = (obj, kee) => {
if (kee in obj) return obj[kee];
for(n of Object.values(obj).filter(Boolean).filter(v => typeof v === 'object')) {
let found = findByKey(n, kee)
if (found) return found
}
}
const findByProperty = (obj, predicate) => {
if (predicate(obj)) return obj
for(n of Object.values(obj).filter(Boolean).filter(v => typeof v === 'object')) {
let found = findByProperty(n, predicate)
if (found) return found
}
}
Run Code Online (Sandbox Code Playgroud)
按值查找会有点不同
let findByValue = (o, val) => {
if (o === val) return o;
if (o === NaN || o === Infinity || !o || typeof o !== 'object') return;
if (Object.values(o).includes(val)) return o;
for (n of Object.values(o)) {
const found = findByValue(n, val)
if (found) return n
}
}
Run Code Online (Sandbox Code Playgroud)
那么它们可以像这样使用
const arry = [{ foo: 0 }, null, { bar: [{ baz: { nutherKey: undefined, needle: "gotcha!" } }]}]
const obj = { alice: Infinity, bob: NaN, charlie: "string", david: true, ebert: arry }
findByKey(obj, 'needle')
// 'gotcha!'
findByProperty(obj, val => val.needle === 'gotcha!')
// { nutherKey: undefined, needle: "gotcha!" }
findByValue(obj, 'gotcha!')
// { nutherKey: undefined, needle: "gotcha!" }
Run Code Online (Sandbox Code Playgroud)
另一个递归解决方案,适用于数组/列表和对象,或两者的混合:
function deepSearchByKey(object, originalKey, matches = []) {
if(object != null) {
if(Array.isArray(object)) {
for(let arrayItem of object) {
deepSearchByKey(arrayItem, originalKey, matches);
}
} else if(typeof object == 'object') {
for(let key of Object.keys(object)) {
if(key == originalKey) {
matches.push(object);
} else {
deepSearchByKey(object[key], originalKey, matches);
}
}
}
}
return matches;
}
Run Code Online (Sandbox Code Playgroud)
用法:
let result = deepSearchByKey(arrayOrObject, 'key'); // returns an array with the objects containing the key
Run Code Online (Sandbox Code Playgroud)
我为此目的创建了库:https : //github.com/dominik791/obj-traverse
您可以使用这样的findFirst()方法:
var foundObject = findFirst(rootObject, 'options', { 'id': '1' });
Run Code Online (Sandbox Code Playgroud)
现在foundObject变量存储对您正在寻找的对象的引用。
小智 6
我通过谷歌搜索找到了类似功能的页面。根据Zach和Regularmike提供的工作,我创建了另一个适合我需要的版本。
顺便说一句,艰巨的工作Zah和Regularmike!我将代码发布在这里:
function findObjects(obj, targetProp, targetValue, finalResults) {
function getObject(theObject) {
let result = null;
if (theObject instanceof Array) {
for (let i = 0; i < theObject.length; i++) {
getObject(theObject[i]);
}
}
else {
for (let prop in theObject) {
if(theObject.hasOwnProperty(prop)){
console.log(prop + ': ' + theObject[prop]);
if (prop === targetProp) {
console.log('--found id');
if (theObject[prop] === targetValue) {
console.log('----found porop', prop, ', ', theObject[prop]);
finalResults.push(theObject);
}
}
if (theObject[prop] instanceof Object || theObject[prop] instanceof Array){
getObject(theObject[prop]);
}
}
}
}
}
getObject(obj);
}
Run Code Online (Sandbox Code Playgroud)
它所做的是找到它的任何对象里面obj有属性名称和值匹配,targetProp并且targetValue,将它推到finalResults阵列。这是可玩的jsfiddle:https ://jsfiddle.net/alexQch/5u6q2ybc/
使用键和谓词改进了@haitaka 答案
function deepSearch (object, key, predicate) {
if (object.hasOwnProperty(key) && predicate(key, object[key]) === true) return object
for (let i = 0; i < Object.keys(object).length; i++) {
let value = object[Object.keys(object)[i]];
if (typeof value === "object" && value != null) {
let o = deepSearch(object[Object.keys(object)[i]], key, predicate)
if (o != null) return o
}
}
return null
}
Run Code Online (Sandbox Code Playgroud)
所以这可以被调用为:
var result = deepSearch(myObject, 'id', (k, v) => v === 1);
Run Code Online (Sandbox Code Playgroud)
或者
var result = deepSearch(myObject, 'title', (k, v) => v === 'Some Recommends');
Run Code Online (Sandbox Code Playgroud)
这是演示:http : //jsfiddle.net/a21dx6c0/
已编辑
以同样的方式,您可以找到多个对象
function deepSearchItems(object, key, predicate) {
let ret = [];
if (object.hasOwnProperty(key) && predicate(key, object[key]) === true) {
ret = [...ret, object];
}
if (Object.keys(object).length) {
for (let i = 0; i < Object.keys(object).length; i++) {
let value = object[Object.keys(object)[i]];
if (typeof value === "object" && value != null) {
let o = this.deepSearchItems(object[Object.keys(object)[i]], key, predicate);
if (o != null && o instanceof Array) {
ret = [...ret, ...o];
}
}
}
}
return ret;
}
Run Code Online (Sandbox Code Playgroud)
some您可以在递归函数中使用 javascript函数。有些的优点是一旦孩子被发现就停止循环。不要使用在大数据下会很慢的地图。
const findChild = (array, id) => {
let result;
array.some(
(child) =>
(child.id === id && (result = child)) ||
(result = findChild(child.options || [], id))
);
return result;
};
findChild(array, 1)
Run Code Online (Sandbox Code Playgroud)
小智 5
找到了我正在寻找的答案,特别是 Ali Alnoaimi 的解决方案。我做了一些小的调整以允许搜索值
function deepSearchByKey(object, originalKey, originalValue, matches = []) {
if (object != null) {
if (Array.isArray(object)) {
for (let arrayItem of object) {
deepSearchByKey(arrayItem, originalKey, originalValue, matches);
}
} else if (typeof object == 'object') {
for (let key of Object.keys(object)) {
if (key == originalKey) {
if (object[key] == originalValue) {
matches.push(object);
}
} else {
deepSearchByKey(object[key], originalKey, originalValue, matches);
}
}
}
}
return matches;
}
Run Code Online (Sandbox Code Playgroud)
使用方法:
let result = deepSearchByKey(arrayOrObject, 'key', 'value');
Run Code Online (Sandbox Code Playgroud)
这将返回包含匹配键和值的对象。