5

This is my actual array :

let mainArray= [
    {
        value: '/AG_TURF-123',
        label: 'Ag & Turf',
        checked: false,
        id:123,
        children: [
            {
                value: '/AG_TURF-123/TRACTOR-456',
                label: 'Tractors',
                checked: false,
                id:456,
                children: [
                    {
                        value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series',
                        label: 'Large (7, 8, 9) Series',
                        checked: false,
                        id:789,
                        children: [{
                            value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series/7-family-tractor',
                            label: '7 Family Tractor',
                            checked: false,
                            id:101112
                        },{
                            value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series/8-family-tractor',
                            label: '8 Family Tractor',
                            checked: false,
                            id:131415
                        },{
                            value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series/9-family-tractor',
                            label: '9 Family Tractor',
                            checked: false,
                            id:161718
                        }],
                    },
                    {
                        value: '/app/Http/routes.js',
                        label: 'routes.js',
                        checked: false,
                        id:181920
                    },
                ],
            },
            {
                value: '/app/Providers',
                label: 'Providers',
                checked: false,
                id:212223,
                children: [{
                    value: '/app/Http/Providers/EventServiceProvider.js',
                    label: 'EventServiceProvider.js',
                    checked: false,
                    id:242526
                }],
            },
        ],
    },
    {
        value: '/config',
        label: 'config',
        checked: false,
        id:272829,
        children: [
            {
                value: '/config/app.js',
                label: 'app.js',
                checked: false,
                id:303132
            },
            {
                value: '/config/database.js',
                label: 'database.js',
                checked: false,
                id:333435
            },
        ],
    },
    {
        value: '/public',
        label: 'public',
        checked: false,
        id:353637,
        children: [
            {
                value: '/public/assets/',
                label: 'assets',
                checked: false,
                id:383940,
                children: [{
                    value: '/public/assets/style.css',
                    label: 'style.css',checked: false,
                    id:404142
                }],
            },
            {
                value: '/public/index.html',
                label: 'index.html',
                checked: false,
                id: 434445
            },
        ],
    },
    {
        value: '/.env',
        label: '.env',
        checked: false,
        id: 464748
    },
    {
        value: '/.gitignore',
        label: '.gitignore',
        checked: false,
        id: 495051
    },
    {
        value: '/README.md',
        label: 'README.md',
        checked: false,
        id: 525354
    },
];

This is my list of value :

const ids=[525354,123,131415];

I want to set checked to true if id matched. My main array may go to 6 to 7 step deep.

What I've done till yet :

setCheckedFlagToItems(checkList, items) {
        return items.map((item) => {
            const node = item;
            if (checkList.indexOf(node.id) !== -1) {
                node.checked = true;
            }
            if ((node.children) && (Array.isArray(node.children) && node.children.length > 0)) {
                this.setCheckedFlagToItems(checkList, node.children);
            }
            return node;
        }, this);
    }

But it not working as usual.

2 Answers 2

15

You could use an iterative and recursice approach with a named function as callback for Array#forEach.

let mainArray = [
{
    value: '/AG_TURF-123', 
    label: 'Ag & Turf', 
    checked: false, 
    id: 123, 
    children: [
        { 
            value: '/AG_TURF-123/TRACTOR-456', 
            label: 'Tractors', 
            checked: false, 
            id: 456, 
            children: [
                { 
                    value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series', 
                    label: 'Large (7, 8, 9) Series', 
                    checked: false, 
                    id: 789, 
                    children: [
                        { 
                            value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series/7-family-tractor', 
                            label: '7 Family Tractor', 
                            checked: false, 
                            id: 101112 
                        }, 
                        { 
                            value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series/8-family-tractor', 
                            label: '8 Family Tractor', 
                            checked: false, 
                            id: 131415 
                        }, 
                        { 
                            value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series/9-family-tractor', 
                            label: '9 Family Tractor', 
                            checked: false, 
                            id: 161718 
                        }
                    ] 
                }, 
                {
                    value: '/app/Http/routes.js', 
                    label: 'routes.js', 
                    checked: false, 
                    id: 181920 
                }
            ]
        }, 
        { 
            value: '/app/Providers', 
            label: 'Providers', 
            checked: false, 
            id: 212223, 
            children: [
                { 
                    value: '/app/Http/Providers/EventServiceProvider.js', 
                    label: 'EventServiceProvider.js', 
                    checked: false, 
                    id: 242526 
                }
            ]
        }
    ]
}, 
{
    value: '/config', 
    label: 'config', 
    checked: false, 
    id: 272829, 
    children: [
        {
            value: '/config/app.js', 
            label: 'app.js', 
            checked: false, 
            id: 303132
        },
        {
            value: '/config/database.js', 
            label: 'database.js', 
            checked: false, 
            id: 333435 
        }
    ]
}, 
{
    value: '/public', 
    label: 'public', 
    checked: false, 
    id: 353637, 
    children: [
        {
            value: '/public/assets/', 
            label: 'assets', 
            checked: false, 
            id: 383940, 
            children: [
                {
                    value: '/public/assets/style.css', 
                    label: 'style.css', 
                    checked: false, 
                    id: 404142
                }
            ]
        }, 
        {
            value: '/public/index.html', 
            label: 'index.html', 
            checked: false, 
            id: 434445 
        }
    ] 
}, 
{ 
    value: '/.env', 
    label: '.env', 
    checked: false, 
    id: 464748 
}, 
{ 
    value: '/.gitignore', 
    label: '.gitignore', 
    checked: false, 
    id: 495051 
}, 
{ 
    value: '/README.md', 
    label: 'README.md', 
    checked: false, 
    id: 525354 
}
],
    ids = [525354, 123, 131415];

mainArray
    .forEach(
        function iter(a) {
            if (ids.includes(a.id)) {
                a.checked = true;
            }
            Array.isArray(a.children) && a.children.forEach(iter);
        }
    );

console.log(mainArray);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

5 Comments

@Kris Hollenbeck, your edit does not really check the array if it is one or not for the recursive iteration, which is necessary.
Hmm.. Maybe I looked at it wrong. It was throwing an error in my IDE. The old code was Array.isArray( (a.children) && a.children.forEach(callback); .. I was getting ) expected. So a missing parenthesis.
Maybe it should have been Array.isArray( a.children) && a.children.forEach(iter); ?
^^ it looks like the original ... and intended.
yeah your right. It was a tslint error I saw I guess. Sorry about that. imgur.com/a/hRMAI
4

If your ids are "unique" (there's only one unique object for each id property), you could also split this action in to two steps:

  1. Make a new data structure that flattens all items in to one object of id: item
  2. Loop through the ids to retrieve the items from this object.

If you find yourself looking up many objects by id, it might be easier to create this interim representation.

The creation of the map uses recursion similar to the other answer: whenever an item contains a children array, it adds those to the map object before it returns.

const mainArray = [{ value: '/AG_TURF-123', label: 'Ag & Turf', checked: false, id: 123, children: [{ value: '/AG_TURF-123/TRACTOR-456', label: 'Tractors', checked: false, id: 456, children: [{ value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series', label: 'Large (7, 8, 9) Series', checked: false, id: 789, children: [{ value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series/7-family-tractor', label: '7 Family Tractor', checked: false, id: 101112 }, { value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series/8-family-tractor', label: '8 Family Tractor', checked: false, id: 131415 }, { value: '/AG_TURF-123/TRACTOR-456/Large-7-8-9-series/9-family-tractor', label: '9 Family Tractor', checked: false, id: 161718 }] }, { value: '/app/Http/routes.js', label: 'routes.js', checked: false, id: 181920 }] }, { value: '/app/Providers', label: 'Providers', checked: false, id: 212223, children: [{ value: '/app/Http/Providers/EventServiceProvider.js', label: 'EventServiceProvider.js', checked: false, id: 242526 }] }] }, { value: '/config', label: 'config', checked: false, id: 272829, children: [{ value: '/config/app.js', label: 'app.js', checked: false, id: 303132 }, { value: '/config/database.js', label: 'database.js', checked: false, id: 333435 }] }, { value: '/public', label: 'public', checked: false, id: 353637, children: [{ value: '/public/assets/', label: 'assets', checked: false, id: 383940, children: [{ value: '/public/assets/style.css', label: 'style.css', checked: false, id: 404142 }] }, { value: '/public/index.html', label: 'index.html', checked: false, id: 434445 }] }, { value: '/.env', label: '.env', checked: false, id: 464748 }, { value: '/.gitignore', label: '.gitignore', checked: false, id: 495051 }, { value: '/README.md', label: 'README.md', checked: false, id: 525354 }];

// We reduce the array of nested items in to one object of:
// { id: item }
const idMap = mainArray.reduce(function merge(map, node) {
  map[node.id] = node;
  
  if (Array.isArray(node.children)) {
    node.children.reduce(merge, map);
  }
  
  return map;
}, {});

const ids = [525354, 123, 131415];

// Whenever you need an item, you can get it
// using idMap[id]
const items = ids.map(id => idMap[id]);
items.forEach(item => item.checked = true);

// or: ids.forEach(id => idMap[id].checked = true)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.