【问题标题】:Dynamically adding more values in Javascript在 Javascript 中动态添加更多值
【发布时间】:2020-11-23 13:36:20
【问题描述】:

如何在 Javascript 中定义的集合中动态添加更多值:

var data1 = [
    { name: 'S1', elems: [0, 1, 2] },
    { name: 'S2', elems: [1, 2, 3] },
    { name: 'S3', elems: [0, 2, 4] },
  ];

我想要做的类似于以下:

    (key, value) = read_a_row_from_table_of_values;
    if (key is present in data1) // could be by iterating all the keys in data 
    {
       data1[key][elems].push(value); // this is the point of concern (how to push values)
    }

由于我将此数据提供给另一个工具 (UpSet),因此必须遵循此数据结构(以名称和元素的形式)。详情请见here。

【问题讨论】:

  • data1 是Array,而不是Map 或object,所以它不能有“键” - 所以请澄清“if( key is present in data1 )”的意思?
  • 是的,钥匙是什么?名字是独一无二的吗?
  • 键是名称(S1 可以说)
  • 困难的部分是什么?如果你只是写出你在 JS 中的伪代码,你就有了解决方案。

标签: javascript dictionary data-structures dynamic


【解决方案1】:

如果您只添加 1 或 2 个项目(即,O(n) 插入时间是可以接受的),那么这个解决方案(基于 @mplungjan 现在已删除的评论)应该适合您:

var data1 = [
    { name: 'S1', elems: [0, 1, 2] },
    { name: 'S2', elems: [1, 2, 3] },
    { name: 'S3', elems: [0, 2, 4] },
  ];

function add( data1, name, value ) {
    const exists = data1.find( e => e.name === name );
    if( exists ) {
        exists.elems.push( value );
    }
    else {
        data1.push( { name, elems: [value] } );
    }
}

add( data1, 'S4', 1 );
add( data1, 'S3', 2 );
add( data1, 'S5', 3 );

如果您要对data1 执行mass 操作,那么您应该首先将其转换为Map(注意Array.prototype.map 和Map<K,V> 是完全不同的东西):

function convertData1ToMap( data1 ) {
    const m = new Map();
    for( const e of data1 ) {
        m.set( e.name, e.elems );
    }
    return m;
}

function convertMapToData1( m ) {
    const arr = [];
    for( const k of map.keys() ) {
        const elems = map.get( k );
        arr.push( { name: k, elems } );
    }
    return arr;
}

//

const m = convertData1ToMap( data1 );

// Mass insert:

for( let i = 4; i < 10 * 1000; i++ ) {
    
    const name = 'S' + i.toString();
    if( m.has( name ) ) {
        m.get( name ).push( i );
    }
    else {
        m.set( name, [i]);
    }
}

// Recreate `data1`:

data1 = convertMapToData1( m );

【讨论】:

  • @mplungjan 因为如果没有匹配项,Array.prototype.find 将返回 undefined。
  • 在那里使用地图的好主意
【解决方案2】:

Entries 和 Find 将起作用

基本上

data1.find(elem => elem.name===key).elems.push(value)

如果 newValues 可能包含不在 data1 数组中的键,我们可以不做单行器

const data1 = [
    { name: 'S1', elems: [0, 1, 2] },
    { name: 'S2', elems: [1, 2, 3] },
    { name: 'S3', elems: [0, 2, 4] },
  ];
const newValues = {"S1": 4,"S2":5, "S6": 6 }

Object.entries(newValues)
  .forEach(([key, value]) => {
    const found = data1.find(elem => elem.name === key);
    if (found) found.elems.push(value);
  });
console.log(data1);

如果要合并,需要添加缺失的键

const data1 = [
    { name: 'S1', elems: [0, 1, 2] },
    { name: 'S2', elems: [1, 2, 3] },
    { name: 'S3', elems: [0, 2, 4] },
  ];
const newValues = {"S1": 4,"S2":5, "S6": 6 }

Object.entries(newValues)
  .forEach(([key, value]) => {
    const found = data1.find(elem => elem.name === key);
    if (found) found.elems.push(value);
    else data1.push({name:key,elems: [value]});
  })
console.log(data1);

【讨论】:

  • 如果应将一个值添加到name 而data1 中不存在,您的解决方案将不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-07
  • 1970-01-01
  • 1970-01-01
  • 2013-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多