JavaScript数组-在同一数组中将元素与其他元素进行比较

4
我将比较JavaScript元素数组中的其他元素。如果元素相同,则必须为所有共同元素赋予相同的编号。如果元素不同,则必须为另一个元素中的所有非相同元素赋予一些不同的数字。
例如:
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}]

在这个数组中,“Number”是一个动态元素,它应该根据以下规则进行填充。
key1 = location + '-' +date;

考虑Key1是第一个元素(位置+日期的组合)。如果数组中存在相同的Key1,则“Number”对于所有相同的Key1都是共同的。
在上面的例子中,{'LA','2017-12-01',1}具有相同的数字1。
{'NY','2017-12-01',2}具有数字2。而{'NY','2016-10-01',3}具有数字3,因为尽管位置相同但日期不同。
请查看下面的代码。
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});
                        }
                }
        }

问题是,for循环正在迭代多次——它一直在多次比较相同的元素。我该如何解决这个问题。

请执行 j<lines.lengthj<i - vibhor1997a
3个回答

3

这似乎是一个适合使用地图的问题。您不应该两次循环遍历数组。

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});
}

非常感谢,它完美地运行了。这里还有一个情况 - 有时 lines[i].date 不可用,在这种情况下,我必须检查另一个字段 lines[i].manufacture_date,如何检查另一个元素。例如:key = lines[i].location + '-' + lines[i].date ? lines[i].date : lines[i].manufacture_date; 就像这样...? - Karthikeyan
为了回答您的问题,我需要您澄清一下:在 lines[i].date 不存在的情况下,但是 lines[i].manufacturing_date 与另一行的日期匹配,它们仍然被视为匹配键吗?例如,如果我们有两个实例 { 'LA', '2017-12-01' },但其中一个具有 '2017-12-01' 作为其日期,而另一个没有日期值,但具有 '2017-12-01' 作为其 manufacturing_date,输出应该是 [{ 'LA', '2017-12-01', 1 }, { 'LA', '2017-12-01', 1 }] 还是 [{ 'LA', '2017-12-01', 1 }, { 'LA', '2017-12-01', 2 }]? - Raghav M
我会用另一种方式解释,Key = lines.location + lines.date 或 lines.manufacture_date。我希望你明白我的意思。如果 lines.date 不存在,则应该考虑 lines.manufacture_date 而不是 lines.date - Karthikeyan
我理解你的意思。我的问题是日期来自哪里是否重要。如果两行具有相同的位置,第二行没有日期,而第一行的日期等于第二行的制造日期,那么输出是什么?它们应该有相同的编号还是不同的? - Raghav M
这是一个空字符串。如果日期不存在。 - Karthikeyan
显示剩余6条评论

1

使用地图可以获得更易读的代码和可能更有效的程序,从O(n²)到O(n),假设访问地图是恒定时间:

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);


1
如果你想要将每个项目相互比较,那么你的最内层for循环从错误的索引开始。目前你的代码是这样的:
for(var j=0;j<lines.length;j++)

相反,你应该从外层循环结束的地方开始,像这样(通过将i增加一)

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

希望这有所帮助!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接