How to avoid loop for loop in javascript

I wrote a piece of code that works great. I want a new array consisting of myArr elements in the order specified in Arr order. However, it uses a for loop inside another for a loop to match the elements of an array.

var myArr = ['a', 'b', 'c', 'd', 'e'];
var orderArr = ['e', 'c'];
var reArr = [];

for (var i = 0; i < orderArr.length; i++) {
  for (var k = 0; k < myArr.length; k++) {
    if (myArr[k] == orderArr[i]) {
      reArr.push(myArr[k]);
    }
  }
}

console.log(reArr);
Run codeHide result

I often heard that using for loops inside another loop is bad practice, and even for Each should be avoided.

How else can I rewrite this code.

+5
source share
9 answers

I would not say that using loops inside loops is a bad practice - in fact, Ori Drree beat me up by saying that the effectiveness of such a practice may simply depend on the size of the data set.

, , . .

, , , , , . JavaScript () "", , .

+4

O (n * m) - n orderArr, m - myArr.

- O (n + m), , Array # O ( m), orderArray O (n).

1: . , , .

2: , myArr . , .

var myArr = ['a', 'b', 'c', 'd', 'e'];
var orderArr = ['e', 'c'];
var myArrDict = myArr.reduce(function(r, s) {
  r[s] = true;
  return r;
}, Object.create(null));

var reArr = orderArr.filter(function(s) {
  return this[s];
}, myArrDict);

console.log(reArr);
Hide result
+3

.

"use strict";

function correlate(
  outer,
  inner, 
  outerKeyOrKeySelector = x => x,
  innerKeyOrKeySelector = x => x
) {
  const outerValues = [...outer];
  const innerValues = [...inner];
  const outerToKey = typeof outerKeyOrKeySelector === 'function'
      ? outerKeyOrKeySelector
      : (x => x[outerKeyOrKeySelector]);

  const innerToKey = typeof innerKeyOrKeySelector === 'function'
      ? innerKeyOrKeySelector
      : (x => x[innerKeyOrKeySelector]);

  const outerKeyed = outerValues.map(value => ({key: outerToKey(value), value});
  const innerKeyed = innerValues.map(value => ({key: innerToKey(value), value});

  return outerKeyed.reduce((results, {key: oKey, value: oValue}) => [
         ...results,
         ...innerKeyed
             .filter(({key: iKey}) => oKey === iKey)
             .map(({value: iValue}) => [oValue, iValue])
    ], []);
}

JOIN .

, YMMV, .

:

reArr = correlate(orderArr, myArr).map(([first, second]) => first);

reArr = correlate(orders, customers, o => o.customer.name, c => c.name)
  .map(([first, second]) => {order: first, customer: second})
  .forEach(({customer, order}) => {
    customer.orders = [...customer.orders, order];
  });
+1

( Ori), , ( . , , , .

- (O (n log n) + O (m log m)), . 3 :

A<B
  We discard A and fetch the next value from the same list A came from
A=B
  We add A to the keep list and retrieve the next value from that array
A>B
  We discard B and retrieve the next value from its list

... , , ...

 O(n log n) + O(m log m) + O(least(n,m))
+1

, - , , ( ) :

var reArr = myArr.filter((n) => orderArr.includes(n));

( IE).

0

ES5 - , :

var myArr = ['a', 'b', 'c', 'd', 'e'];
var orderArr = ['e', 'c'];
var myArrIndex = {};

for(var i=0;i < myArr .length; i++){
    myArrIndex[myArr[i]]=myArr[i];
}; 

for(var i=0;i < orderArr.length; i++){
        var orderArrayItem = orderArr[i];
        if (myArrIndex[orderArrayItem]){
            reArr.push(orderArrayItem);
        }
}


console.log(reArr);
0

myArr . 'a' myArr 'f' orderArr.

var myArr = ['a', 'a', 'b', 'c', 'd', 'e'];
var orderArr = ['e', 'c', 'f']
var myObj = createObjectFrom(myArr);
var reArr = [];

function createObjectFrom(array) {
   var obj = {};
   var arrValue;

   for (var i = 0; i < array.length; i++) {
     arrValue = array[i];

     if (obj[arrValue]) {
       obj[arrValue]++;
     } else {
       obj[arrValue] = 1;
     }
   }

   return obj;  // { 'a': 2, 'b': 1, 'c': 1, 'd': 1, 'e': 1 }
}

var orderValue;

for(var i=0;i<orderArr.length;i++){
  orderValue = orderArr[i];

  if (myObj.hasOwnProperty(orderValue)) {
     for (var j = 0; j < myObj[orderValue]; j++) {
       reArr.push(orderValue);
     }
   }
}

console.log(reArr);  // [ "c", "e" ]

(6 * 3 =) 18 (6 + 3 =) 9 .

, , (j).


, , , , :

https://www.youtube.com/watch?v=XKu_SEDAykw

0

, , , reduce :

var myArr = ['a', 'b', 'c', 'd', 'e'];
var orderArr = ['e', 'c'];
// Merge the two arrays
var reArr = myArr.concat(orderArr);

let result = reArr.reduce((arr, val) => {
  // return only equal values that are not already in the new array
  // If the value is in the new array 'indexOf()' will be greater than -1
  // we will then not modify the current array
  //
  // If the value is not in the new array and is equal to the current lookup 
  // then add it to the filter. Once filtered, we can check
  // if the filter contains more than one item if it does
  // then we can add it to the new array
  return reArr.filter(v => v == val && arr.indexOf(val) == -1).length > 1 
    // If it is not in the new array add it using 'concat()'
    // otherwise we will return the current array as is
    ? arr.concat(val) : arr
}, [])

console.log(result);
Hide result
0

You can take Mapand collect all the same values ​​in an array for subsequent concatenation with a set of results.

var array = ['a', 'b', 'c', 'd', 'e'],
    order = ['e', 'c'],
    map = new Map,
    result;
    
array.forEach(v => map.set(v, (map.get(v) || []).concat(v)));

result = order.reduce((r, v) => r.concat(map.get(v)), []);

console.log(result);
Run codeHide result
0
source

Source: https://habr.com/ru/post/1692602/


All Articles