0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

TypeScript オブジェクトを結合したいなら、shallow copy か lodash.merge で?

Posted at

背景

DynamoDB に対する CommandInput を、条件によって切り替えたかった。

イメージとしては、以下の FilterExpression を On/Off したかった

Expression
const params = {
    ExpressionAttributeNames: {
        "#PK": uid,
        "#timestamp": "timestamp"
    },
    ExpressionAttributeValues: {
        ":PK": userID,
        ":sortkeyval1": startDate.getTime(),
        ":sortkeyval2": endDate.getTime()
    },
    KeyConditionExpression: "#PK = :PK"
    FilterExpression: "#timestamp BETWEEN :sortkeyval1 AND :sortkeyval2"
}

結論

スプレッド構文を使って、浅いコピーを利用する

merge する部分が微妙な感じになってしまうけど、まぁ、ライブラリも使わなくて済む

merge
const keyCondition = {
    ExpressionAttributeNames: {
        "#PK": "uid",
    },
    ExpressionAttributeValues: {
        ":PK": userID,
    },
    KeyConditionExpression: "#PK = :PK",
}
const filterExpression = {
    ExpressionAttributeNames: {
        "#timestamp": "timestamp"
    },
    ExpressionAttributeValues: {
        ":sortkeyval1": startDate.getTime(),
        ":sortkeyval2": endDate.getTime(),
    },
    FilterExpression: "#timestamp BETWEEN :sortkeyval1 AND :sortkeyval2"
}
const params = (withFilter)? 
    {...keyCondition, ...filterExpression, ExpressionAttributeNames: {...keyCondition.ExpressionAttributeNames, 
        ...filterExpression.ExpressionAttributeNames}, ExpressionAttributeValues: {...keyCondition.ExpressionAttributeValues, ...filterExpression.ExpressionAttributeValues}}:
    keyCondition;

lodash を使う場合

merge by lodash
import _ from "lodash";
const paramsMerged =  (withFilter)? 
    _.merge(keyCondition, filterExpression):
    keyCondition;

結果

どちらも以下になる。分かりやすさとしては lodash でしょうねぇ

merged result
{
  ExpressionAttributeNames: { 
    '#PK': 'uid', 
    '#timestamp': 'timestamp' 
  },
  ExpressionAttributeValues: {
    ':PK': 'uid',
    ':sortkeyval1': 1672148172970,
    ':sortkeyval2': 1672148172970
  },
  KeyConditionExpression: '#PK = :PK',
  FilterExpression: '#timestamp BETWEEN :sortkeyval1 AND :sortkeyval2'
}

スプレッド構文の試行

スプレッド構文自体の理解の為に、色々試してみた

var content1 = {
    id: "1",
    timestamp: 123
  }
var content2 = {
  uid2: "2"
};
var content3 = {
  id: "3"
};
var value = "4";
var value2 = "5";
var content4 = {
  type: {
    audience: "people",
  }
};
var content5 = {
  type: {
    audience: "animal",
    author: "person",
    batchSize: 5,
  },
  id: 1,
}

console.log({value, ...content1}, "変数とオブジェクト");
console.log({value, ...content1, value2}, "変数とオブジェクト2");
console.log({nameChanged: value, ...content1}, "変数に名前を付けて");
console.log({...{value}, ...content1, }, "オブジェクトにして");
console.log({...{nameChanged: value}, ...content1, }, "オブジェクトにして名前を付けて");
console.log({...content2, ...content1, }, "オブジェクト同士を");
console.log({...{content2}, ...content1, }, "さらにオブジェクト化");
console.log({...{nameChanged: content2}, ...content1, }, "オブジェクトの名前を付けて");

console.log({...content2, ...content1, ...content3, }, "同一プロパティの上書き id = 1 / 3");

console.log({...content5, ...content4, type: {...content5.type, ...content4.type}}, "プロパティにオブジェクトがある場合");

結果

プロパティ名を変更しながら Merge したい時や、変数を組み込みつつって時に便利そう。
一番最後のが、上の結論に利用したプロパティ単位での浅いコピー(shallow copy)

result
{ value: '4', id: '1', timestamp: 123 } // 変数とオブジェクト
{ value: '4', id: '1', timestamp: 123, value2: '5' } // 変数とオブジェクト2
{ nameChanged: '4', id: '1', timestamp: 123 } // 変数に名前を付けて
{ value: '4', id: '1', timestamp: 123 } // オブジェクトにして
{ nameChanged: '4', id: '1', timestamp: 123 } // オブジェクトにして名前を付けて
{ uid2: '2', id: '1', timestamp: 123 } // オブジェクト同士を
{ content2: { uid2: '2' }, id: '1', timestamp: 123 } // さらにオブジェクト化
{ nameChanged: { uid2: '2' }, id: '1', timestamp: 123 } // オブジェクトの名前を付けて
{ uid2: '2', id: '3', timestamp: 123 } // 同一プロパティの上書き id = 1 / 3
{ type: { audience: 'people', author: 'person', batchSize: 5 }, id: 1 } // プロパティにオブジェクトがある場合

あとがき

スプレッド構文を知らなかったけれど、オブジェクトを結合ってだけで以下に辿り着けて助かりました。感謝

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?