Path: csiph.com!weretis.net!feeder7.news.weretis.net!news.mb-net.net!open-news-network.org!.POSTED.247.232.197.178.dynamic.wless.lssmb00p-cgnat.res.cust.swisscom.ch!not-for-mail From: Thomas 'PointedEars' Lahn Newsgroups: comp.lang.javascript Subject: Re: Search array of objects Date: Mon, 24 Feb 2020 12:23:05 +0100 Organization: PointedEars Software (PES) Lines: 109 Message-ID: <2373271.grBdAzqF5M@PointedEars.de> References: Reply-To: Thomas 'PointedEars' Lahn Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8Bit Injection-Info: gwaiyur.mb-net.net; posting-host="247.232.197.178.dynamic.wless.lssmb00p-cgnat.res.cust.swisscom.ch:178.197.232.247"; logging-data="11847"; mail-complaints-to="abuse@open-news-network.org" User-Agent: KNode/4.14.10 Cancel-Lock: sha1:PDjmPLWPsdVXoka+rfBvTirEJwo= X-Face: %i>XG-yXR'\"2P/C_aO%~;2o~?g0pPKmbOw^=NT`tprDEf++D.m7"}HW6.#=U:?2GGctkL,f89@H46O$ASoW&?s}.k+&. On 24/02/2020 12:10 pm, Andrew Poulos wrote: >> I have an array of 50+ arrays each containing 300+ objects as elements. Technically it is not actually containing the objects, but just the references to them. You can use that to your advantage (see below). >> Each individual object looks like >> >> { >> type: "text", >> id: "text01", >> content: "Turn to left", >> disabled: false, >> bg: "small.jpg" >> } >> >> So the entire array looks like >> >> [ >> [obj1, obj2, obj3...], >> [obj1, obj2, obj3...], >> [obj1, obj2, obj3...], >> ... >> ] >> >> That is, every sub-array has the same number of objects: 'content', >> 'disabled' and 'bg' may differ from sub-array to sub-array. >> >> I need to change the value of 'bg' for the "same" five objects across >> all the sub-arrays. >> >> Currently I'm looping through the top level array and then each object >> in a sub-array looking for the objects in question. Is there a more >> efficient way to do this without looping? > > I tried this (nesting forEach): > > slides.forEach(s => { > s.forEach(item => { You should rename “s” to “slide”. > if (item.type == 'text' && item.hasOwnProperty('content')) { If you can make sure beforehand that the prototype chain of “item” is empty (and you should), then you can use the “in” operator which might be more efficient that multiple .hasOwnProperty() calls. A simple way to achieve that is obj = Object.create(null, Object.getOwnPropertyDescriptors(obj)); You can still use methods of Object.prototype on this object by calling them directly on it. JSX:object.js has (deprecated, master) jsx.object.getDataObject() and (trunk) jsx.object.createDataObject() for this purpose, but it does not use the new approach yet. > item.disabled = !chk; // a value set earlier You are not doing here what you described above. > } > }; > }); > > and it seems to work. Is this a good approach? Probably yes; I would not do it much differently. If you operate on the same data structure or data several times, you can use Array.prototype.filter() to retrieve an array of references to only those objects that are of interest, and subsequently only use that array: const contentObjs = []; slides.forEach(slide => { contentObjs.push.apply( contentObjs, slide.filter(item => 'content' in item) ); }); PoC (suitable to experiment with in the script console): var contentObjs = []; [[{content: 42}, {no_content: 23}]].forEach(slide => { contentObjs.push.apply( contentObjs, slide.filter(item => 'content' in item) ); }); /* “[{…}]” */ console.log(contentObjs); However, you appear to be doing something like this a lot recently; you might want to look into Microsoft LINQ, which is a specification for an API and a library with implementations in various languages (including ECMAScript implementations) that is specifically designed to handle arrays of objects efficiently. -- PointedEars FAQ: | | Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.