简体   繁体   English

如何根据对象上的键进行映射?

[英]How to map according to key on objects?

I'm trying to map through object values and add text if the key is right on JavaScript.如果键在 JavaScript 上是正确的,我正在尝试映射对象值并添加文本。 Here is our object:这是我们的对象:

{
    "id": "n27",
    "name": "Thomas More",
    "className": "level-1",
    "children": [
        {
            "id": "n1",
            "name": "Rousseau",
            "className": "level-2",
            "children": [
                {
                    "id": "n2",
                    "name": "Machiavelli",
                    "className": "level-3",
                    "children": [
                        {
                            "id": "n9",
                            "name": "Edison, Thomas",
                            "className": "level-4"
                        }
                    ]
                }
            ]
        },
        {
            "id": "n3",
            "name": "Einstein",
            "className": "level-2",
            "children": [
                {
                    "id": "n10",
                    "name": "Arf, Cahit",
                    "className": "level-3",
                    "children": [
                        {
                            "id": "n15",
                            "name": "Rawls, John",
                            "className": "level-4"
                        }
                    ]
                },
                {
                    "id": "n12",
                    "name": "Smith, Adam",
                    "className": "level-3",
                    "children": [
                        {
                            "id": "n11",
                            "name": "Kant, Immanuel",
                            "className": "level-4"
                        }
                    ]
                }
            ]
        },
        {
            "id": "n60",
            "name": "Turing, Alan",
            "className": "level-2"
        }
    ]
}

I want to add " YES" to their className 's.我想在他们的className添加" YES" So new object should look like this:所以新对象应该是这样的:

{
    "id": "n27",
    "name": "Thomas More",
    "className": "level-1 YES",
    "children": [
        {
            "id": "n1",
            "name": "Rousseau",
            "className": "level-2 YES",
            "children": [
                {
                    "id": "n2",
                    "name": "Machiavelli",
                    "className": "level-3 YES",
                    "children": [
                        {
                            "id": "n9",
                            "name": "Edison, Thomas",
                            "className": "level-4 YES"
                        }
                    ]
                }
            ]
        },
        {
            "id": "n3",
            "name": "Einstein",
            "className": "level-2 YES",
            "children": [
                {
                    "id": "n10",
                    "name": "Arf, Cahit",
                    "className": "level-3 YES",
                    "children": [
                        {
                            "id": "n15",
                            "name": "Rawls, John",
                            "className": "level-4 YES"
                        }
                    ]
                },
                {
                    "id": "n12",
                    "name": "Smith, Adam",
                    "className": "level-3 YES",
                    "children": [
                        {
                            "id": "n11",
                            "name": "Kant, Immanuel",
                            "className": "level-4 YES"
                        }
                    ]
                }
            ]
        },
        {
            "id": "n60",
            "name": "Turing, Alan",
            "className": "level-2 YES"
        }
    ]
}

I have tried this, but it adds to all of the keys:我试过这个,但它增加了所有的键:

const addToClassName = (datasource, fn) => {
    return Object.fromEntries(Object
        .entries(datasource, fn)
        .map(([k, v]) => [k, v && v.children != undefined && v.children.length > 0 ? addToClassName(v.children, fn) : fn(v)])
    );
}

let res = addToClassName(obj, v => v + ' YEP');

How can I do it?我该怎么做?

You don't need to use Object.fromEntries() , instead, you make your function return a new object, with a transformed className based on the return value of fn .您不需要使用Object.fromEntries() ,而是让您的函数返回一个新对象,并根据fn的返回值转换后的className You can then set the children: key on the object to be a mapped version of all the objects inside of the children array.然后,您可以将对象上的children:键设置为 children 数组内所有对象的映射版本。 When mapping, you can pass each child into the recursive call to your addToClassName() function.映射时,您可以将每个子项传递到对addToClassName()函数的递归调用中。 You can add the children key conditionally to the output object but checking if it exists (with children && ) and then by spreading the result using the spread syntax ... :您可以有条件地将children键添加到输出对象,但检查它是否存在(使用children && ),然后使用 spread 语法传播结果...

 const data = { "id": "n27", "name": "Thomas More", "className": "level-1", "children": [ { "id": "n1", "name": "Rousseau", "className": "level-2", "children": [ { "id": "n2", "name": "Machiavelli", "className": "level-3", "children": [ { "id": "n9", "name": "Edison, Thomas", "className": "level-4" } ] } ] }, { "id": "n3", "name": "Einstein", "className": "level-2", "children": [ { "id": "n10", "name": "Arf, Cahit", "className": "level-3", "children": [ { "id": "n15", "name": "Rawls, John", "className": "level-4" } ] }, { "id": "n12", "name": "Smith, Adam", "className": "level-3", "children": [ { "id": "n11", "name": "Kant, Immanuel", "className": "level-4" } ] } ] }, { "id": "n60", "name": "Turing, Alan", "className": "level-2" } ] }; const addToClassName = (obj, fn) => ({ ...obj, className: fn(obj.className), ...(obj.children && {children: obj.children.map(child => addToClassName(child, fn))}) }); console.log(addToClassName(data, v => v + " YES"));

If you can change the current obj object then you can achieve this using recursion as如果您可以更改当前的obj对象,那么您可以使用递归实现这一点

function addClass(obj) {
  obj.className += " YES";
  obj.children && obj.children.forEach(addClass);
}

 const obj = { id: "n27", name: "Thomas More", className: "level-1", children: [ { id: "n1", name: "Rousseau", className: "level-2", children: [ { id: "n2", name: "Machiavelli", className: "level-3", children: [ { id: "n9", name: "Edison, Thomas", className: "level-4", }, ], }, ], }, { id: "n3", name: "Einstein", className: "level-2", children: [ { id: "n10", name: "Arf, Cahit", className: "level-3", children: [ { id: "n15", name: "Rawls, John", className: "level-4", }, ], }, { id: "n12", name: "Smith, Adam", className: "level-3", children: [ { id: "n11", name: "Kant, Immanuel", className: "level-4", }, ], }, ], }, { id: "n60", name: "Turing, Alan", className: "level-2", }, ], }; function addClass(obj) { obj.className += " YES"; obj.children && obj.children.forEach(addClass); } addClass(obj); console.log(obj);

You can use lodash , if don't mind.如果不介意,您可以使用lodash

const _ = require('lodash');
const data = { "id": "n27", "name": "Thomas More", "className": "level-1", "children": [ { "id": "n1", "name": "Rousseau", "className": "level-2", "children": [ { "id": "n2", "name": "Machiavelli", "className": "level-3", "children": [ { "id": "n9", "name": "Edison, Thomas", "className": "level-4" } ] } ] }, { "id": "n3", "name": "Einstein", "className": "level-2", "children": [ { "id": "n10", "name": "Arf, Cahit", "className": "level-3", "children": [ { "id": "n15", "name": "Rawls, John", "className": "level-4" } ] }, { "id": "n12", "name": "Smith, Adam", "className": "level-3", "children": [ { "id": "n11", "name": "Kant, Immanuel", "className": "level-4" } ] } ] }, { "id": "n60", "name": "Turing, Alan", "className": "level-2" } ] };

const newData= _.cloneDeepWith(data, (val, key) => (
  (key === 'className') ? `${val} YES` : _.noop()
));

console.log(newData);
// {
//   id: 'n27',
//   name: 'Thomas More',
//   className: 'level-1 YES',
// ...
// }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM