鉴于这种结构,我如何在这个深层嵌套的对象结构中找到具有给定id的对象。
const menuItems = [
{
id: 1,
imageUrl: "http://placehold.it/65x65",
display: "Shop Women",
link: "#",
type: "image",
nextItems: [
{
id: 10,
display: "홈",
link: "#",
type: "menuitem"
},
{
id: 20,
display: "의류",
link: "#",
type: "menuitem-withmore",
nextItems: [
{
id: 100,
display: "I'm inside one nest",
link: "#",
type: "menuitem"
}
]
},
{
id: 30,
display: "가방",
link: "#",
type: "menuitem-withmore",
nextItems: []
},
{
id: 40,
display: "신발",
link: "#",
type: "menuitem-withmore",
nextItems: []
},
{
id: 50,
display: "악세서리",
link: "#",
type: "menuitem-withmore",
nextItems: []
},
{
id: 60,
display: "SALE",
link: "#",
type: "menuitem-withmore",
style: "bold",
nextItems: []
},
{
id: 70,
display: "브랜드",
link: "#",
type: "menuitem-withmore",
nextItems: []
},
{
type: "separator"
},
{
id: 80,
display: "위시리스트",
link: "#",
type: "menuitem"
},
{
id: 90,
display: "고객센터",
link: "#",
type: "menuitem"
},
{
id: 99,
display: "앱 다운로드",
link: "#",
type: "menuitem"
}
]
},
{
id: 2,
imageUrl: "http://placehold.it/65x65",
display: "Shop Men",
link: "#",
type: "image",
nextItems: [
{
id: 95,
display: "MEN's ITEMS.",
link: "#",
type: "menuitem"
}
]
}
];
让我们说我想找到id: 20
的对象并将其返回:
{
id: 20,
display: "의류",
link: "#",
type: "menuitem-withmore",
nextItems: [
{
id: 100,
display: "I'm inside one nest",
link: "#",
type: "menuitem"
}
]
},
我似乎无法找到如何使用lodash,而且这个软件包可能解决了我的问题,但我无法理解如何使其适用于我的用例
答案 0 :(得分:7)
使用DFS。
import React from 'react'
import {Field, FieldArray, reduxForm} from 'redux-form'
import validate from './validate'
const renderField = ({input, label, type, meta: {touched, error}}) => (
<div>
<label>{label}</label>
<div>
<input {...input} type={type} placeholder={label} />
{touched && error && <span>{error}</span>}
</div>
</div>
)
const renderHobbies = ({fields, meta: {error}}) => (
<ul>
<li>
<button type="button" onClick={() => fields.push()}>Add Hobby</button>
</li>
{fields.map((hobby, index) => (
<li key={index}>
<button
type="button"
title="Remove Hobby"
onClick={() => fields.remove(index)}
/>
<Field
name={hobby}
type="text"
component={renderField}
label={`Hobby #${index + 1}`}
/>
</li>
))}
{error && <li className="error">{error}</li>}
</ul>
)
const renderMembers = ({fields, meta: {error, submitFailed}}) => (
<ul>
<li>
<button type="button" onClick={() => fields.push({})}>Add Member</button>
{submitFailed && error && <span>{error}</span>}
</li>
{fields.map((member, index) => (
<li key={index}>
<button
type="button"
title="Remove Member"
onClick={() => fields.remove(index)}
/>
<h4>Member #{index + 1}</h4>
<Field
name={`${member}.firstName`}
type="text"
component={renderField}
label="First Name"
/>
<Field
name={`${member}.lastName`}
type="text"
component={renderField}
label="Last Name"
/>
<FieldArray name={`${member}.hobbies`} component={renderHobbies} />
</li>
))}
</ul>
)
const FieldArraysForm = props => {
const {handleSubmit, pristine, reset, submitting} = props
return (
<form onSubmit={handleSubmit}>
<Field
name="clubName"
type="text"
component={renderField}
label="Club Name"
/>
<FieldArray name="members" component={renderMembers} />
<div>
<button type="submit" disabled={submitting}>Submit</button>
<button type="button" disabled={pristine || submitting} onClick={reset}>
Clear Values
</button>
</div>
</form>
)
}
export default reduxForm({
form: 'fieldArrays', // a unique identifier for this form
})(FieldArraysForm)
答案 1 :(得分:1)
也许这有帮助
menuItems.map(item => {
if (item.id === 10) return item;
});
BTW我没有考虑这个解决方案的效率。
答案 2 :(得分:1)
我会这样做
const menuItems = [
{
id: 1,
imageUrl: "http://placehold.it/65x65",
display: "Shop Women",
link: "#",
type: "image",
nextItems: [
{
id: 10,
display: "홈",
link: "#",
type: "menuitem"
},
{
id: 20,
display: "의류",
link: "#",
type: "menuitem-withmore",
nextItems: [
{
id: 100,
display: "I'm inside one nest",
link: "#",
type: "menuitem"
}
]
},
{
id: 30,
display: "가방",
link: "#",
type: "menuitem-withmore",
nextItems: []
},
{
id: 40,
display: "신발",
link: "#",
type: "menuitem-withmore",
nextItems: []
},
{
id: 50,
display: "악세서리",
link: "#",
type: "menuitem-withmore",
nextItems: []
},
{
id: 60,
display: "SALE",
link: "#",
type: "menuitem-withmore",
style: "bold",
nextItems: []
},
{
id: 70,
display: "브랜드",
link: "#",
type: "menuitem-withmore",
nextItems: []
},
{
type: "separator"
},
{
id: 80,
display: "위시리스트",
link: "#",
type: "menuitem"
},
{
id: 90,
display: "고객센터",
link: "#",
type: "menuitem"
},
{
id: 99,
display: "앱 다운로드",
link: "#",
type: "menuitem"
}
]
},
{
id: 2,
imageUrl: "http://placehold.it/65x65",
display: "Shop Men",
link: "#",
type: "image",
nextItems: [
{
id: 95,
display: "MEN's ITEMS.",
link: "#",
type: "menuitem"
}
]
}
];
var data = [];
menuItems.forEach(function(item) {
item.nextItems.forEach(function(element) {
data.push(element)
}, this);
}, this);
console.log(_.where(data, {id: 20}));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
答案 3 :(得分:1)
您可以尝试使用此功能,它将随着深度变化而动态工作
function findNodeById(nodes, id, callback?) {
let res;
function findNode(nodes, id) {
for (let i = 0; i < nodes.length; i++) {
if (nodes[i].id === id) {
res = nodes[i];
// you can also use callback back here for more optioins ;)
// callback(nodes[i]);
break;
}
if (nodes[i].nextItems) {
findNode(nodes[i].nextItems, id);
}
}
}
findNode(nodes, id)
return res;
}
findNodeById(menuItems, 99) // { id: 99, display: "앱 다운로드", link: "#", type: "menuitem" }
答案 4 :(得分:-3)
如果你正在使用lodash,你只需要 .find(collection,[predicate = .identity])。
所以你想要这样的东西:
const menuItems = [
{
id: 1,
imageUrl: "http://placehold.it/65x65",
display: "Shop Women",
link: "#",
type: "image",
nextItems: [
{
id: 10,
display: "홈",
link: "#",
type: "menuitem"
},
{
id: 20,
display: "의류",
link: "#",
type: "menuitem-withmore",
nextItems: [
{
id: 100,
display: "I'm inside one nest",
link: "#",
type: "menuitem"
}
]
},
{
id: 30,
display: "가방",
link: "#",
type: "menuitem-withmore",
nextItems: []
},
{
id: 40,
display: "신발",
link: "#",
type: "menuitem-withmore",
nextItems: []
},
{
id: 50,
display: "악세서리",
link: "#",
type: "menuitem-withmore",
nextItems: []
},
{
id: 60,
display: "SALE",
link: "#",
type: "menuitem-withmore",
style: "bold",
nextItems: []
},
{
id: 70,
display: "브랜드",
link: "#",
type: "menuitem-withmore",
nextItems: []
},
{
type: "separator"
},
{
id: 80,
display: "위시리스트",
link: "#",
type: "menuitem"
},
{
id: 90,
display: "고객센터",
link: "#",
type: "menuitem"
},
{
id: 99,
display: "앱 다운로드",
link: "#",
type: "menuitem"
}
]
},
{
id: 2,
imageUrl: "http://placehold.it/65x65",
display: "Shop Men",
link: "#",
type: "image",
nextItems: [
{
id: 95,
display: "MEN's ITEMS.",
link: "#",
type: "menuitem"
}
]
}
];
function dfs(obj, targetId) {
if (obj.id === targetId) {
return obj
}
if (obj.nextItems) {
for (let item of obj.nextItems) {
let check = dfs(item, targetId)
if (check) {
return check
}
}
}
return null
}
let result = null
for (let obj of menuItems) {
result = dfs(obj, 100)
if (result) {
break
}
}
console.dir(result)