4

Am comparing javascript array of elements with other elements within the same array. If elements are same means, i have to give same number for all the common elements. If the elements are different i have to give some different number for all the non identical elements in another element.

for example :

Array structure = [{Location, Date, Number}]


array = [{ 'LA','2017-12-01',1},
         { 'LA','2017-12-01',1},
         { 'NY','2017-12-01',2},
         { 'NY','2016-10-01',3},
         { 'LA','2017-12-01',1},
         { 'LA','2017-12-01',1},
         { 'LA','2017-12-01',1}]

In this array 'Number' is dynamic element, It should be populate on the following rules.

key1 = location + '-' +date;

Consider Key1 is the first element ( combination of location + date ). If the same key1 is present in the array, then 'Number' is common for all the same Key1.

In the above example {'LA','2017-12-01',1 } having the same number 1.

{ 'NY','2017-12-01',2} having the number 2. and { 'NY','2016-10-01',3}, having the number 3 because eventhough location is common but date is different.

Please find my code below.

var item = this.state.item;
var lines = item.order_items;
var count=1;
var key1;
var key2;

    for(var i=0;i<lines.length;i++)
        {
            key1 = lines[i].location + '-' + lines[i].date;

            for(var j=0;j<lines.length;j++)
                {
                    key2 = lines[j].location + '-' + lines[j].date;
                    if( key1 === key2 )
                        {
                            lines[i].number=count;
                            this.setState({item:item});
                        }
                    else
                        {
                            count++;
                            lines[j].number=count;
                            this.setState({item:item});
                        }
                }
        }

Problem is, for loop is iterating multiple times - its keep on comparing the same element multiple times. how do i can solve this issue.

1
  • do j<lines.length to j<i Commented Dec 9, 2017 at 6:35

3 Answers 3

3

This seems like the sort of problem well suited for a map. You shouldn't be looping over the array twice.

var item = this.state.item;
var lines = item.order_items;
var map = new Map();
for (var i = 0; i < lines.length; i++) {
    key = lines[i].location + '-' + lines[i].date;
    if (!map.has(key)) {
        map.set(key, map.size + 1);
    }
    lines[i].number = map.get(key);
    this.setState({item: item});
}
Sign up to request clarification or add additional context in comments.

11 Comments

Thanks a lot., it works perfectly. one more case here - Some times lines[i].date wont be available, in this case i have to check for another field lines[i].manufacture_date how do i check for another element. for example : key = lines[i].location + '-' + lines[i].date ? lines[i].date : lines[i].manufacture_date; like this...??
To answer your question, I need you to clarify: in the case where lines[i].date doesn't exist, but lines[i].manufacturing_date matches the date for another line, are they still considered matching keys? For example, if we have two instances of { 'LA', '2017-12-01' }, but one has '2017-12-01' as it's date and the other has no date value but '2017-12-01' as it's manufacturing_date, should the output be [{ 'LA', '2017-12-01', 1 }, { 'LA', '2017-12-01', 1 }] or [{ 'LA', '2017-12-01', 1 }, { 'LA', '2017-12-01', 2 }] ?
I will explain in another way, Key = lines.location + lines.date or lines.manufacture_date. I hope you got my point. if lines.date is not there, then it should consider lines.manufacture_date instead of lines.date.
I understand what you are saying. My question is whether it matters where the date came from. If two lines have the same location, Line 2 has no date, and Line 1's date equals Line 2's manufacturing date, what is the output? Should they have the same number or not?
Okay, thanks. Replace the 5th line with var key = lines[i].location + '-' + (lines[i].date ? lines[i].date : lines[i].manufacture_date);
|
1

If you are trying to compare each item to one another, your innermost for loop is starting at the wrong index. Currently you have

for(var j=0;j<lines.length;j++)

Instead, you should begin where your outer loop left off, like so (by incrementing i by one)

for(var j=i+1;j<lines.length;j++)

Hope this helps!

Comments

1

Using a map you could get a more readable code and probably a more efficient program, O(n²) to O(n) assuming that accessing a map is in constant time :

var n = 0;
var map = {};
var xs = [
  ['LA', '2017-12-01'],
  ['LA', '2017-12-01'],
  ['NY', '2017-12-01'],
  ['NY', '2016-10-01'],
  ['LA', '2017-12-01'],
  ['LA', '2017-12-01'],
  ['LA', '2017-12-01']
];

xs = xs.map(function (x) {
  var label = x[0] + "-" + x[1];
  if (!map[label]) map[label] = ++n;
  return x.concat([map[label]]);
});

console.log(xs);

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.